编组指向数组结构的指针

时间:2014-07-30 09:22:24

标签: c# arrays pointers struct marshalling

我正在尝试为一个为c / cpp编写的力传感器调用驱动程序DLL。工作的Cpp代码如下所示:

我是随dll一起提供的头文件,结构是这样定义的

typedef struct
{
  DWORD usb_hid_idx;
  int open;
  char vid_pid[256];
  char dev_info[256];
  char sn_info[256];
  int hw_info;
  unsigned char hw_var;
  int fw_vers;
} t_DeviceInfo;

我需要调用的函数定义如下:

extern "C" DLL_API int Search(t_DeviceInfo *p_dev_info);

在主代码中,我只创建一个前面定义的t_DeviceInfo结构的数组和一个指向第一个元素的指针,并用这个指针调用函数Search

t_DeviceInfo deviceInfo[16];
t_DeviceInfo* deviceInfoPtr = &deviceInfo[0];
int ret = search(deviceInfoPtr);

至少在那里,一切正常。使用C#,它目前看起来像这样:

unsafe public struct t_DeviceInfo
{
    long usb_hid_idx;
    int open;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    char[] vid_pid;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    char[] dev_info;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    char[] sn_info;
    int hw_info;
    char hw_var;
    int fw_vers;
}

unsafe public class ASTAS
{
    [DllImport("ASTAS_DLL.dll")]
    public extern static int Search(t_DeviceInfo* devInfPtr);
}

主要是:

t_DeviceInfo[] devInfo = new t_DeviceInfo[16];

但那是关于它的。如何将结构数组封送到固定的内存位置并将相应的指针传递给Search()

2 个答案:

答案 0 :(得分:3)

这里不需要unsafe。你也可以删除它。并且您的结构声明不正确。有些类型是错误的。 C ++ DWORD是无符号的32位值。 C#long是带符号的64位值。 C ++ unsigned char是无符号的8位值。 C#char是一个16位字符。通常unsigned char会映射到byte

结构应该是:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct t_DeviceInfo
{
    uint usb_hid_idx;
    int open;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    string vid_pid;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    string dev_info;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    string sn_info;
    int hw_info;
    byte hw_var;
    int fw_vers;
}

函数声明应为:

[DllImport("ASTAS_DLL.dll")]
public extern static int Search([In] t_DeviceInfo[] devInfPtr);

这假定调用约定是stdcall。它看起来好像它实际上是cdecl。在这种情况下,您需要:

[DllImport("ASTAS_DLL.dll", CallingConvention=CallingConvention.Cdecl)]
public extern static int Search([In] t_DeviceInfo[] devInf);

我使用了[In]编组。您可能需要根据语义对其进行修改,我无法从提供的信息中辨别出来。

答案 1 :(得分:0)