c# - 如何在 C# 中处理来自 C DLL 文件的复杂结构返回类型?

标签 c# c pointers struct marshalling

我一直在尝试使用 C# 中的一些简单测试代码来获取 C 库 (DLL)。到目前为止,我已经能够很好地导入和使用简单的函数。我现在遇到的问题是我不知道如何从这个导入的函数接收复杂的结构返回类型。

这是两个函数签名:

C:

#define HID_API_EXPORT __declspec(dllexport)
#define HID_API_CALL

struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id);

C#:

[DllImport("hidapi.dll")]
public static extern hid_device_info hid_enumerate(ushort vendor_id, ushort product_id);

这是两个结构:

C:

struct hid_device_info {
    char *path;
    unsigned short vendor_id;
    unsigned short product_id;
    wchar_t *serial_number;
    unsigned short release_number;
    wchar_t *manufacturer_string;
    wchar_t *product_string;
    unsigned short usage_page;
    unsigned short usage;
    int interface_number;

    struct hid_device_info *next;
};

C#:

[StructLayout(LayoutKind.Sequential)]
public struct hid_device_info
{
    public IntPtr path;
    public ushort vendorid;
    public ushort productid;
    public IntPtr serialnumber;
    public ushort releasenumber;
    public IntPtr manufacturer;
    public IntPtr product;
    public ushort usagepage;
    public ushort usage;
    public int interfacenumber;

    public IntPtr next;
}

我目前在运行程序时遇到此错误:

Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\tajensen\Documents\hidapiCS\hidapitest\bin\Debug\hidapitest.vshost.exe'.

Additional information: A call to PInvoke function 'hidapiCS!hidapiCS.hidapi::hid_enumerate' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我做了一些挖掘,我唯一能找到的东西描述了如何接收非常简单结构的返回类型(即没有指针,只有基本类型,如 int 和 bool)。我真的很感激对这个问题有一些额外的见解,因为我知道我想去哪里,但我对这种代码的了解还不够多,无法自行深入研究。

提前致谢, 汤姆斯

最佳答案

你的结构看起来不错,没有任何改变它包装的命令行标志。

可能是因为这条线

#define HID_API_CALL

这意味着您正在使用默认调用约定,通常是 __cdecl。因此,将 P/Invoke 定义更改为:

[DllImport("hidapi.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern hid_device_info hid_enumerate(ushort vendor_id, ushort product_id);

所以在C端如何管理栈的规则是正确的。

关于c# - 如何在 C# 中处理来自 C DLL 文件的复杂结构返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38512400/

相关文章:

c# - 帮助刚接触 C# 变量的人

c++ - 双对齐

c++ - 64 位 T 的 std::vector<T*> 与 std::vector<T>

c++ - 使用算术符号来遍历字符串

c# - 将线程本地资源与并行 for 循环一起使用

c# - 构建器设计模式在现实生活中的用途是什么?

c - C 中的单链表(警告)

c - 如何通过引用传递 union 成员

c# - 使用 C# 通过单击按钮从 MS Access 数据库中删除数据

c - 正在重新分配的指针未分配