简体   繁体   English

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

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

I've been trying to get a C library (DLL) working with some simple test code in C#. 我一直在尝试让C库(DLL)与C#中的一些简单测试代码一起使用。 So far I've been able to import and use the simple functions just fine. 到目前为止,我已经能够导入和使用简单的功能了。 The issue I'm having right now is that I don't know how to receive the complex struct return type from this imported function. 我现在遇到的问题是,我不知道如何从导入的函数中接收复杂的结构返回类型。

Here are the two function signatures: 这是两个函数签名:

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#: C#:

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

And here are the two structs: 这是两个结构:

C: 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#: 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;
}

I'm currently getting this error when I run the program: 我目前在运行程序时遇到此错误:

Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\\Users\\tajensen\\Documents\\hidapiCS\\hidapitest\\bin\\Debug\\hidapitest.vshost.exe'. 托管调试助手“ PInvokeStackImbalance”已在“ 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. 附加信息:对PInvoke函数'hidapiCS!hidapiCS.hidapi :: hid_enumerate'的调用已使堆栈不平衡。 This is likely because the managed PInvoke signature does not match the unmanaged target signature. 这可能是因为托管PInvoke签名与非托管目标签名不匹配。 Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature. 检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

I've done a bit of digging and the only things I've been able to find describe how to receive return types of very simple structs (ie no pointers, and only basic types like ints and bools). 我做了一些挖掘,发现的唯一内容描述了如何接收非常简单的结构的返回类型(即,没有指针,只有基本类型,如ints和bools)。 I would really appreciate some additional insight on the issue, as I know where I want to be, but I don't know enough about this kind of code to dig deeper on my own. 我确实很高兴对这个问题有一些其他的见解,因为我知道我想去哪里,但是我对这种代码的了解还不够,无法自己深入研究。

Thanks in advance, Toms 预先感谢,汤姆斯

Your structure looks good, baring any command line flags that change the packing of it. 您的结构看起来不错,禁止任何更改其包装的命令行标志。

Likely, it's because of this line 可能是因为这条线

#define HID_API_CALL

This means you're using the default calling convention, which is generally __cdecl . 这意味着您正在使用默认的调用约定,通常为__cdecl So, change the P/Invoke definition to: 因此,将P / Invoke定义更改为:

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

So the rules for how to manage the stack on the C side are followed properly. 因此,正确遵循了如何在C侧管理堆栈的规则。

There is a tool named SWIG , a code generation tool, connects programs written in C and C++ with a variety of high-level programming languages like c#. 有一个名为SWIG的工具,它是一种代码生成工具,可以将用C和C ++编写的程序与各种高级编程语言(如c#)连接起来。 It generates wrapper code for twenty three different target languages: 它为二十三种不同的目标语言生成包装器代码:

It's very powerful for these tasks, specially data type/pointer conversion and many others. 对于这些任务,特别是数据类型/指针转换以及许多其他任务,它非常强大。 It saves manual conversion. 它节省了手动转换。

Try to use this tool to generate C# code for your case and finally compiled Dll. 尝试使用此工具为您的案例生成C#代码,最后编译Dll。

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

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

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

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