C# Interop - 如何传递可由 C 作为结构数组访问的 C# 结构
C# Interop - How to pass a C# struct that can be accessed by C as an array of structs
我目前正在尝试让非托管 (c) DLL 在我的 C# 应用程序中工作。我遇到的问题是将结构传递给非托管函数。
我已经像这样导入了函数(使用 PInvoke 互操作助手)...
[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint = "ListDevices")]
public static extern int ListDevices(ref Device_t devices, ref int DevicesCount);
我要传递的结构...
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct Device_t
{
/// int
public int Address;
/// int
public int GearAddress;
/// int
public int Id;
/// char[8]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 8)]
public string Rev;
}
DLL代码中的函数(无关代码已删除)...
static int listDevices(Device_t *devices, int *deviceCount)
{
char *pch;
int i;
char *token;
int paramCount;
Device_t device;
// code removed //
while (token != NULL)
{
pch = strstr(token, "ENTRY");
if (pch != NULL)
{
paramCount = sscanf(&token[0], "%*d ..... %d",
&device.Address, &device.GearAddress, &device.Rev,
&device.Id);
if (paramCount == 4)
{
devices[i].Address = device.Address;
devices[i].GearAddress = device.GearAddress;
devices[i].Id = device.Id;
strcpy(devices[i].Rev, device.Rev);
i++;
}
}
token = strtok(NULL, "#");
}
// code removed //
}
主要问题是 c 代码将 'Device_t devices' 变量作为数组访问,但 c# 函数只接受单数 Device_t。
我相信结构中存在一个字符串使其不可 blittable,使事情进一步复杂化:(
理想情况下,我希望能够在 c# 中声明一个 Device_t 的数组,它可以被 c 访问,但是我知道数组在 c# 中的结构与 c 不同。
我发现了问题,这是我编组 DLL 函数的方式。
需要指定 In 和 Out 属性。
[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint = "ListDevices")]
public static extern int ListDevices([In, Out] Device_t[] devices, ref int DevicesCount);
我目前正在尝试让非托管 (c) DLL 在我的 C# 应用程序中工作。我遇到的问题是将结构传递给非托管函数。
我已经像这样导入了函数(使用 PInvoke 互操作助手)...
[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint = "ListDevices")]
public static extern int ListDevices(ref Device_t devices, ref int DevicesCount);
我要传递的结构...
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct Device_t
{
/// int
public int Address;
/// int
public int GearAddress;
/// int
public int Id;
/// char[8]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 8)]
public string Rev;
}
DLL代码中的函数(无关代码已删除)...
static int listDevices(Device_t *devices, int *deviceCount)
{
char *pch;
int i;
char *token;
int paramCount;
Device_t device;
// code removed //
while (token != NULL)
{
pch = strstr(token, "ENTRY");
if (pch != NULL)
{
paramCount = sscanf(&token[0], "%*d ..... %d",
&device.Address, &device.GearAddress, &device.Rev,
&device.Id);
if (paramCount == 4)
{
devices[i].Address = device.Address;
devices[i].GearAddress = device.GearAddress;
devices[i].Id = device.Id;
strcpy(devices[i].Rev, device.Rev);
i++;
}
}
token = strtok(NULL, "#");
}
// code removed //
}
主要问题是 c 代码将 'Device_t devices' 变量作为数组访问,但 c# 函数只接受单数 Device_t。 我相信结构中存在一个字符串使其不可 blittable,使事情进一步复杂化:(
理想情况下,我希望能够在 c# 中声明一个 Device_t 的数组,它可以被 c 访问,但是我知道数组在 c# 中的结构与 c 不同。
我发现了问题,这是我编组 DLL 函数的方式。
需要指定 In 和 Out 属性。
[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint = "ListDevices")]
public static extern int ListDevices([In, Out] Device_t[] devices, ref int DevicesCount);