Chr*_*ris 1 c# pinvoke winapi marshalling data-structures
我在PInvoking SetupDiCreateDeviceInfoList时发现了这个.
C++函数签名是:
HDEVINFO SetupDiCreateDeviceInfoList(
_In_opt_ const GUID *ClassGuid,
_In_opt_ HWND hwndParent
);
Run Code Online (Sandbox Code Playgroud)
在C#中我定义了GUID这样的结构:
[StructLayout(LayoutKind.Sequential)]
public struct GUID
{
public uint Data1;
public ushort Data2;
public ushort Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data4;
}
Run Code Online (Sandbox Code Playgroud)
和这样的功能:
[DllImport("Setupapi.dll")]
public static extern IntPtr SetupDiCreateDeviceInfoList(GUID ClassGuid, IntPtr hwndParent);
Run Code Online (Sandbox Code Playgroud)
由于在C#结构中默认情况下通过副本传递(与类不同),因此该函数签名不应匹配.确实在32位运行时调用该函数时:
GUID classGuid = new GUID();
IntPtr deviceInfoSet = SetupDiCreateDeviceInfoList(classGuid, IntPtr.Zero);
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
SetupDiCreateDeviceInfoList'使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
但是在64位运行时,上面的代码可以工作.为什么???
当然,如果我通过引用传递结构,则该函数在32位和64位运行时都能正常工作:
[DllImport("Setupapi.dll")]
public static extern IntPtr SetupDiCreateDeviceInfoList(ref GUID ClassGuid, IntPtr hwndParent);
GUID classGuid = new GUID();
IntPtr deviceInfoSet = SetupDiCreateDeviceInfoList(ref classGuid, IntPtr.Zero);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
447 次 |
| 最近记录: |