Как исправить «Тип метода не совместим с PInvoke» - PullRequest
0 голосов
/ 31 октября 2019

При попытке вернуть структуру с точным расположением, как в 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 (структура c ++)) и строку (c # struct), тогда я бы не получил ошибку, поэтому я знаю, что этоОсновная проблема, и я не знаю, как решить эту часть.

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

1 Ответ

0 голосов
/ 31 октября 2019

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

void _stdcall TestAcq2(tVDACQ_CallBackRecVal *retval)
...