繁体   English   中英

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

[英]How do I handle a complex struct return type from a C DLL file within C#?

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

这是两个函数签名:

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;
}

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

托管调试助手“ PInvokeStackImbalance”已在“ C:\\ Users \\ tajensen \\ Documents \\ hidapiCS \\ hidapitest \\ bin \\ Debug \\ hidapitest.vshost.exe”中检测到问题。

附加信息:对PInvoke函数'hidapiCS!hidapiCS.hidapi :: hid_enumerate'的调用已使堆栈不平衡。 这可能是因为托管PInvoke签名与非托管目标签名不匹配。 检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

我做了一些挖掘,发现的唯一内容描述了如何接收非常简单的结构的返回类型(即,没有指针,只有基本类型,如ints和bools)。 我确实很高兴对这个问题有一些其他的见解,因为我知道我想去哪里,但是我对这种代码的了解还不够,无法自己深入研究。

预先感谢,汤姆斯

您的结构看起来不错,禁止任何更改其包装的命令行标志。

可能是因为这条线

#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侧管理堆栈的规则。

有一个名为SWIG的工具,它是一种代码生成工具,可以将用C和C ++编写的程序与各种高级编程语言(如c#)连接起来。 它为二十三种不同的目标语言生成包装器代码:

对于这些任务,特别是数据类型/指针转换以及许多其他任务,它非常强大。 它节省了手动转换。

尝试使用此工具为您的案例生成C#代码,最后编译Dll。

从以下网址下载二进制文件: http : //prdownloads.sourceforge.net/swig/swigwin-3.0.10.zip

对于教程: http : //www.swig.org/tutorial.html

暂无
暂无

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

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