Как исправить «Тип метода несовместим с PInvoke»

Пытаясь вернуть структуру с точным макетом, как в C++, проблема заключается в том, что TCHAR rMsg[256] включен в структуру C++, а [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public char rMsg;включен в структуру C# (оба будут показаны ниже). Я получаю сообщение об ошибке "Тип метода несовместим с PInvoke" .

Я также должен указать, что C++ не мой, и я не могу его изменить, поскольку для других функций требуется макет структуры, приведенный ниже.

Я знаю, что проблема в TCHAR, поскольку, когда я комментирую соответствующие строки в C++ и C#, я не получаю ошибку.

Я вызываю созданную мной .dll (которую я также включу в приведенный ниже код) только для того, чтобы вернуть структуру, чтобы знать, что у меня правильный синтаксис.

C++:

extern "C" {
    __declspec(dllexport) tVDACQ_CallBackRecVal (  _stdcall TestAcq2())
    {   
                //Just adding random values so I know it works.
        tVDACQ_CallBackRecVal AR;
        AR.rFlags = 1;
        AR.rFrameHeight = 10;
        AR.rFrameWidth = 10;
        return AR;
    }
}
//Struct
typedef struct {
    int    rFlags,           
        rType,             
        rEvent,           
        rSocket;          
    TCHAR  rMsg[256]; //Has to stay as TCHAR       
    int    rFrameWidth,      
        rFrameHeight;      
    short* rFrameBuffer;      
    union {
        int    rCaptureRows;      
        int    rCaptureFrames;    
    };
    int    rCapturePercent;   
    void* rUserCallBackProc, 
        * rUserParam;       
    int    rAborted;          
    void* rPacketData;       
    int    rFGControl;        
} tVDACQ_CallBackRecVal;

C#:

//Simply calling the .dll
[DllImport("C:\\Users\\jch\\source\\repos\\FlatPanelSensor\\x64\\Debug\\VADAV_AcqS.dll", EntryPoint = "TestAcq2", CallingConvention = CallingConvention.Cdecl)]
        public unsafe static extern tVDACQ_CallBackRec TestAcq2();
 [StructLayout(LayoutKind.Sequential)]
        public struct tVDACQ_CallBackRec
        {
            public int rFlags;
            public int rType;
            public int rEvent;
            public int rSocket;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string rMsg; //I believe this is the issue

            public int rFrameWidth;
            public int rFrameHeight;

            public IntPtr rFrameBuffer;

            public int rCaptureRows;
            public int rCaptureFrames;
            public int rCapturePercent;

            public IntPtr rUserCallBackProc;
            public IntPtr rUserParam;

            public int rAborted;

            public IntPtr rPacketData;

            public int rFGControl;
        }
//Then I just call the function
tVDACQ_CallBackRec testStruct= TestAcq2();

Я бы ожидал, что структура имеет все компоненты, как определено, но вместо этого я получаю сообщение об ошибке, как указано в заголовке.

Опять же, если бы я не включал TCHAR (структура С++) и строку (структура С#), я бы не получил ошибку, поэтому я знаю, что это основная проблема, и я не знаю, как решить эту часть.

РЕДАКТИРОВАТЬ: для решения см. Первый комментарий от @David Heffernan


person Joe Halpin    schedule 31.10.2019    source источник
comment
Измените прототип так, чтобы структура передавалась в качестве аргумента функции по ref, void _stdcall TestAcq2(tVDACQ_CallBackRecVal* retval)   -  person David Heffernan    schedule 31.10.2019
comment
У меня все работает спасибо за помощь! Это не позволит мне отметить ваш комментарий как полезный ответ.   -  person Joe Halpin    schedule 31.10.2019


Ответы (1)


Самый простой способ решить эту проблему — изменить прототип так, чтобы структура передавалась в качестве аргумента функции по ссылке:

void _stdcall TestAcq2(tVDACQ_CallBackRecVal *retval)
person David Heffernan    schedule 31.10.2019