PInvoke一个结构指针来获取数据

时间:2014-09-17 13:38:58

标签: c# pinvoke marshalling dllimport

C代码:

// Device description structure
struct DeviceInfo
{
  unsigned short deviceID;
  unsigned short productID;
  unsigned short versionNumber;
  wchar_t* deviceName;
}; 

void __cdecl GetAttachedDevices(
  int* count,
  DeviceInfo* deviceInfoList
);

和PInvoke C#代码使用这个C DLL:

    public struct DeviceInfo
    {
        public ushort deviceID;
        public ushort productID;
        public ushort versionNumber;
        public IntPtr deviceName;
    }; 

    [DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl)]
    public static extern void GetAttachedDevices(ref int count, ref DeviceInfo deviceInfoList);

当我使用这个C#代码时:

    int count = 0;
    DeviceInfo dev = new DeviceInfo();

    GetAttachedDevices(ref count, ref dev);

我只在 dev 中获得一个设备信息(当 count 中有2个设备时)。

如何获取所有设备数据?

2 个答案:

答案 0 :(得分:3)

您需要分配并传递数组。声明这样的函数:

[DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void GetAttachedDevices(
    ref int count, 
    [In, Out] DeviceInfo[] deviceInfoList
);

这样称呼:

int count = 16; // not sure how you are expected to come up with this value
DeviceInfo[] dev = new DeviceInfo[count];

GetAttachedDevices(ref count, dev);

如何分配数组?也许该函数允许您为数组传递空指针以获取所需的大小。在这种情况下你有:

int count = 0;
GetAttachedDevices(ref count, null);
DeviceInfo[] dev = new DeviceInfo[count];
GetAttachedDevices(ref count, dev);

您将能够从C代码或其文档中找出这些详细信息。

答案 1 :(得分:1)

GetAttachedDevices可能需要一个数组,所以你应该修改你的第二个参数。

问题是:这个数组是由GetAttachedDevices分配的(然后谁应该销毁它?),还是它希望你提供数组?

如果是后者,它如何处理你提供的数组不够大的情况?它是否将前N个设备复制到数组并返回所需的总数,大于数组长度,期望您用更大的数组重新调用GetAttachedDevices?