C K*_*iew 5 c c# pinvoke marshalling
请耐心等待,因为我是新来的编组人员.我有一个C结构和函数声明如下:
typedef struct
{
char* name;
BT_ADDR address;
} DeviceList;
extern "C" _declspec(dllexport)DeviceList* PerformQuery();
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)
运行C#程序后,返回NotSupportedException.你能告诉我我的编组有什么问题吗?
一个问题是编组器无法判断返回的数组中有多少项,这意味着它无法对其进行编组。
PerformQuery() API 是否有其他方法来确定数组的长度?
如果它只返回 1 个项目,您可能希望使其返回 IntPtr,然后使用 Marshal.PtrToStructure(),如下所述:
更新:
您可以尝试像这样的 C 接口 - 即一个函数返回项目数,另一个函数用项目填充预先分配的数组。
extern "C" _declspec(dllexport) int GetQueryNumItems();
extern "C" _declspec(dllexport) void GetQueryItems(DeviceList* items);
Run Code Online (Sandbox Code Playgroud)
那么 C# 定义将如下所示:
[DllImport("BT_Conn.dll")]
public extern static int GetQueryNumItems();
[DllImport("BT_Conn.dll")]
public extern static void GetQueryItems([In, Out] DeviceList[] items);
Run Code Online (Sandbox Code Playgroud)
您可以在 C# 中这样称呼它:
int numItems = GetQueryNumItems();
DeviceList[] items = new DeviceList[numItems];
GetQueryItems(items);
Run Code Online (Sandbox Code Playgroud)
当连接 C# 和 C++ 时,我通常发现创建 C++/CLI 类库更容易,它提供了一个在混合 DLL 中包装 C 代码的托管接口。但是,如果您在 CE 上运行,则该选项可能不可用。
| 归档时间: |
|
| 查看次数: |
2133 次 |
| 最近记录: |