首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用可以接受多种不同类型的参数p/调用函数?

如何使用可以接受多种不同类型的参数p/调用函数?
EN

Stack Overflow用户
提问于 2013-04-21 01:21:17
回答 1查看 1.1K关注 0票数 0

看一看:

代码语言:javascript
复制
[DllImport("User32.dll")]
public static extern StatusCode DisplayConfigGetDeviceInfo(
    ref IDisplayConfigInfo a
);

现在我的结构继承自IDisplayConfigInfo:

代码语言:javascript
复制
var displayConfigTargetDeviceName = new DisplayConfigTargetDeviceName
{
    header = new DisplayConfigDeviceInfoHeader
    {
        adapterId = targetModeInfo.adapterId,
        id = targetModeInfo.id,
        size = Marshal.SizeOf(typeof(DisplayConfigTargetDeviceName)),
        type = DisplayConfigDeviceInfoType.GetTargetName,
    }
};
var configTargetDeviceName = (IDisplayConfigInfo) displayConfigTargetDeviceName;
var retval = CCDWrapper.DisplayConfigGetDeviceInfo(ref configTargetDeviceName);

现在出现了一个问题。retval返回"InvalidParameter“值。为什么会这样呢?这是因为我尝试使用接口,但我不明白为什么。

当我明确地说DisplayConfigGetDeviceInfo()接受DisplayConfigTargetDeviceName而不是接口,并将displayconfigTargetDeviceName直接传递给它时,它就可以工作了。

问题是,我不想为每个结构创建8-9个重载。请注意,C++版本只有一个重载。它会从我传递的指针中找出剩下的部分。

// structs:

代码语言:javascript
复制
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DisplayConfigTargetDeviceName : IDisplayConfigInfo
{
    public DisplayConfigDeviceInfoHeader header;
    public DisplayConfigTargetDeviceNameFlags flags;
    public DisplayConfigVideoOutputTechnology outputTechnology;
    public ushort edidManufactureId;
    public ushort edidProductCodeId;
    public uint connectorInstance;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 
    public string monitorFriendlyDeviceName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string monitorDevicePath;
}

[StructLayout(LayoutKind.Sequential)]
public struct DisplayConfigDeviceInfoHeader
{
    public DisplayConfigDeviceInfoType type;
    public int size;
    public LUID adapterId;
    public uint id;
}

IDisplayConfig接口为空。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-21 02:40:49

多亏了David,我能够想出聪明的解决方案(Imo),它似乎工作得很好。

代码语言:javascript
复制
[DllImport("User32.dll")]
private static extern StatusCode DisplayConfigSetDeviceInfo(IntPtr requestPacket);
public static StatusCode DisplayConfigSetDeviceInfo<T>(ref T displayConfig) 
   where T : IDisplayConfigInfo
{
    return WrapStructureAndCall(ref displayConfig, DisplayConfigSetDeviceInfo);
}


[DllImport("User32.dll")]
private static extern StatusCode DisplayConfigGetDeviceInfo(IntPtr targetDeviceName);
public static StatusCode DisplayConfigGetDeviceInfo<T>(ref T displayConfig) 
  where T : IDisplayConfigInfo
{
    return WrapStructureAndCall(ref displayConfig, DisplayConfigGetDeviceInfo);
}

public static StatusCode WrapStructureAndCall<T>(ref T displayConfig,
    Func<IntPtr, StatusCode> func) where T : IDisplayConfigInfo
{
    var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(displayConfig));
    Marshal.StructureToPtr(displayConfig, ptr, false);

    var retval = func(ptr);

    displayConfig = (T)Marshal.PtrToStructure(ptr, displayConfig.GetType());

    Marshal.FreeHGlobal(ptr);
    return retval;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16123108

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档