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

前端 未结 2 436
小蘑菇
小蘑菇 2021-01-14 19:07

I have a DLL with interface

struct modeegPackage
{
    uint8_t     version;    // = 2
    uint8_t     count;      // packet counter. Increases by 1 each pack         


        
相关标签:
2条回答
  • 2021-01-14 19:38

    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. 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. 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. 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.

    0 讨论(0)
  • 2021-01-14 19:55

    The answer marked as an "ANSWER" before mine is not really correct and it has been 1.5 years.

    The reason the OP got that error is indeed just what the error description says, "Method's type signature is not PInvoke compatible"

    When you have a C/C++ function such as the one declared below,

        __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,

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

    So your P/Invoke declaration should be,

        [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.

    0 讨论(0)
提交回复
热议问题