简体   繁体   English

调用DLL方法时,方法的类型签名与PInvoke不兼容

[英]Method's type signature is not PInvoke compatible while calling DLL method

I have a DLL with interface 我有一个带有接口的DLL

struct modeegPackage
{
    uint8_t     version;    // = 2
    uint8_t     count;      // packet counter. Increases by 1 each packet
    uint16_t    data[6];    // 10-bit sample (= 0 - 1023) in big endian (Motorola) format
    uint8_t     switches;   // State of PD5 to PD2, in bits 3 to 0
};

__declspec(dllexport) void __cdecl initSerial();

__declspec(dllexport) void __cdecl closeSerialPort();

__declspec(dllexport) struct modeegPackage __cdecl getPackage();

And C# adapter 和C#适配器

class EEGCommunication
{
    [StructLayout(LayoutKind.Sequential)]
    public struct modeegPackage
    {

        /// unsigned char
        public byte version;

        /// unsigned char
        public byte count;

        /// unsigned int[6]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.U2)]
        public UInt16[] data;

        /// unsigned char
        public byte switches;
    }

    private const string DLL = "libneureader-lib.dll";

    [DllImport(DLL, EntryPoint = "_Z10initSerialv")]
    public static extern void InitSerial();

    [DllImport(DLL, EntryPoint = "_Z15closeSerialPortv")]
    internal static extern void CloseSerialPort();

    [DllImport(DLL, EntryPoint = "_Z10getPackagev", CallingConvention = CallingConvention.Cdecl)]
    public static extern modeegPackage GetPackage();
}

But when I'm trying to call GetPackage method, I receive an error Method's type signature is not PInvoke compatible. 但是,当我尝试调用GetPackage方法时,收到错误消息Method's type signature is not PInvoke compatible.

What's wrong with my code? 我的代码有什么问题?

UPDATE: Code updated 更新:代码已更新

The answer marked as an "ANSWER" before mine is not really correct and it has been 1.5 years. 在我的面前被标记为“ ANSWER”的答案并不是真的正确,并且已经存在了1.5年。

The reason the OP got that error is indeed just what the error description says, "Method's type signature is not PInvoke compatible" OP出现该错误的原因确实是错误描述所言,“方法的类型签名与PInvoke不兼容”

When you have a C/C++ function such as the one declared below, 当您拥有C / C ++函数(例如下面声明的函数)时,

    __declspec(dllexport) struct modeegPackage __cdecl getPackage();

Since the function returns a value of struct which is bigger than any register can hold, GCC compiler will try to optimize it(Return Value Optimize), so the actual implementation looks like the following, 由于该函数返回的struct值大于任何寄存器可以容纳的值,因此GCC编译器将尝试对其进行优化(Return Value Optimize),因此实际实现如下所示:

    __declspec(dllexport) void __cdecl getPackage(struct* modeegPackage);

So your P/Invoke declaration should be, 因此,您的P / Invoke声明应为

    [DllImport(DLL, EntryPoint = "_Z10getPackagev", CallingConvention = CallingConvention.Cdecl)]
    public static extern GetPackage(out modeegPackage);

I hope my answer help any other developers who may have similar issue in the future. 希望我的回答对以后可能遇到类似问题的其他开发人员有所帮助。

It is the array that is causing the problem. 正是导致问题的阵列。 The pinvoke marshaller doesn't like dealing with it in the specific case of returning a structure by value as a function return value. 在按值返回结构作为函数返回值的特定情况下,pinvoke编组器不喜欢处理它。 It is in general troublesome, the way this is done is highly compiler dependent. 通常很麻烦,此方法高度依赖于编译器。 With good odds that you'll have trouble since it sounds like you are using GCC. 很可能您会遇到麻烦,因为听起来您正在使用GCC。 It is typically done by the caller allocating space for the return value on the stack and passing a pointer to it. 通常通过调用方在堆栈上为返回值分配空间并向其传递指针来完成。

A crude but effective trick is to expand the array yourself, practical enough since it has only 6 elements. 一个简单但有效的技巧是自己扩展数组,因为它只有6个元素,因此非常实用。 Substitute the array like this: 像这样替换数组:

        /// unsigned int[6]
        public short data0;
        public short data1;
        //...
        public short data5;

Which will solve the exception. 这将解决异常。 Whether you'll get the data correctly remains to be seen, if not then you may have to switch to MSVC. 是否能够正确获取数据还有待观察,否则,您可能不得不切换到MSVC。

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

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