繁体   English   中英

C结构到C#的编组

[英]Marshalling of C structure to C#

请耐心等待,因为我是新来的编组人员。 我有一个C结构和函数声明如下:

typedef struct 
{
    char* name;
    BT_ADDR address;
} DeviceList;

extern "C" _declspec(dllexport)DeviceList* PerformQuery();

BT_ADDR结构与Win CE SDK中wsbth2.h中定义的结构相同。 PerformQuery返回指向DeviceList数组的指针。

在我的C#程序中,我执行以下pinvoke声明,如下所示

[StructLayout(LayoutKind.Sequential)]
struct DeviceList
{
    public string name;
    public ulong address;
}

[DllImport("BT_Conn.dll")]
public extern static DeviceList[] PerformQuery();

运行C#程序后,返回NotSupportedException。 你能告诉我我的编组有什么问题吗?

一个问题是编组器无法判断返回的数组中有多少项,这意味着它无法编组它。

PerformQuery()API是否有其他方法来确定数组的长度?

如果它只返回1个项目,你可能想让它返回一个IntPtr,然后使用Marshal.PtrToStructure(),如下所述:

p / invoke返回指向struct的指针的C函数

更新:

您可以尝试这样的C接口 - 即一个返回项目数的函数,另一个用项填充预先分配的数组。

extern "C" _declspec(dllexport) int GetQueryNumItems(); 
extern "C" _declspec(dllexport) void GetQueryItems(DeviceList* items); 

然后C#定义看起来像这样:

[DllImport("BT_Conn.dll")]  
public extern static int GetQueryNumItems();
[DllImport("BT_Conn.dll")]  
public extern static void GetQueryItems([In, Out] DeviceList[] items);

你会在C#中称之为:

int numItems = GetQueryNumItems();
DeviceList[] items = new DeviceList[numItems];
GetQueryItems(items);

在连接C#和C ++时,我通常会发现创建一个C ++ / CLI类库更容易,它提供了一个包装C代码的托管接口,在一个混合的DLL中。 但是,如果您在CE上运行,则可能无法使用该选项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM