如何解决“方法类型与PInvoke不兼容”的问题

时间:2019-10-31 09:15:33

标签: c# c++ struct dllimport tchar

尝试返回与C ++中的布局完全相同的结构,问题在于,当public static int tap_counter(String type) { String[] type_array = type.split(""); String[] example_letters = new String[] {"A","B"}; int total = 0; for(int i=0; i < type_array.length;i++){ for(int j=0; type_array[i] != standard_letters[j]; j++) { if(type_array[i] == "A") total += 1; else if(type_array[i] == "B") total += 2; } } return total; } 被包含在C ++结构中而TCHAR rMsg[256]被包含在C#结构中时(两者都将在下面显示)我收到错误消息“方法的类型与PInvoke不兼容”。

我还应该指出C ++不是我的,并且我不能更改它,因为其他函数需要下面给出的结构布局。

我知道问题是TCHAR,因为当我注释掉C ++和C#中的相关行时,我没有得到错误。

我正在调用我创建的.dll(还将在下面的代码中包括它)以返回一个结构,以便使我知道我的语法正确。

C ++:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
 public char rMsg;
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;
    }
}

C#:

//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;
//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;
        }

我希望结构具有定义的所有组件,但我却得到标题中所述的错误。

同样,如果我不包括TCHAR(c ++结构)和字符串(c#结构),那么我不会收到错误,所以我知道这是潜在的问题,我也不知道如何解决该问题

编辑: 有关解决方案,请参阅@David Heffernan的第一条评论

1 个答案:

答案 0 :(得分:0)

解决此问题的最简单方法是更改​​原型,以便ref将结构作为参数传递给函数:

void _stdcall TestAcq2(tVDACQ_CallBackRecVal *retval)