【问题标题】:How to fix 'Method's type is not PInvoke Compatible'如何修复“方法的类型与 PInvoke 不兼容”
【发布时间】:2020-02-26 14:51:28
【问题描述】:

试图返回一个与 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++ struct) 和 string (c# struct),那么我不会收到错误,所以我知道这是根本问题,我不知道如何解决该部分.

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

【问题讨论】:

  • 更改原型,以便将结构作为参数传递给 ref,void _stdcall TestAcq2(tVDACQ_CallBackRecVal* retval)
  • 我得到了它的工作谢谢你的帮助!它不会让我将您的评论标记为有用的答案。

标签: c# c++ struct dllimport tchar


【解决方案1】:

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

void _stdcall TestAcq2(tVDACQ_CallBackRecVal *retval)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2021-01-07
    • 2019-06-18
    相关资源
    最近更新 更多