【问题标题】:How to fix 'Method's type signature is not PInvoke compatible' error in C#如何修复 C# 中的“方法的类型签名与 PInvoke 不兼容”错误
【发布时间】:2020-02-15 09:05:06
【问题描述】:

我只需要知道如何从具有以下结构的 C++ 中的 PInvoke 返回结构。目前我可以处理它是空白的,我只想知道如何在代码中设置的条件下返回结构。

我已经尝试使用我需要返回的整个结构并隔离结构的每个部分以了解哪个部分给我带来了问题(这将在提供的代码中显而易见)。

我尝试了相同的方法,希望在结构中返回几个整数,效果很好。 (尝试使用 ***, ___ 使这个粗体)

//.header file
typedef struct { //Defintion of my struct in C++

    TCHAR  msg[256];

}testTCHAR;

//.cpp file
extern "C" {
    __declspec(dllexport) testTCHAR* (_stdcall TestChar(testTCHAR* AR))
    {
        AR->msg;
        return AR;
    }
}

在我的 C# 中,我将 .dll 称为:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void testChar(testTCHAR AR);

[DllImport("C:\\Users\\jch\\source\\repos\\FlatPanelSensor\\x64\\Debug\\VADAV_AcqS.dll", EntryPoint = "TestCallBackChar", CallingConvention = CallingConvention.Cdecl)]
        public unsafe static extern testTCHAR TestCallBackChar([MarshalAs(UnmanagedType.FunctionPtr)] testChar call);

//Struct
public struct testTCHAR
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string rMsg; //I assume the error should be fixed here 
                                  but to what exactly I don't know.
        }

//Defining the callback
testChar tChar =
                (test) =>
                {
                    //As far as I'm aware this part can be left blank
                      as I followed a tutorial online
                };

testTCHAR returned = TestCallBackChar(tChar); //This is where the error 
                                                happens

我只需要返回结构体,最好附上一个值。

我得到的错误是“方法的类型签名与 PInvoke 不兼容。”这在标题中,但我涵盖了所有基础。

如果您需要更多有关这方面的信息,请询问,我应该能够提供。

【问题讨论】:

    标签: c# c++ struct


    【解决方案1】:

    由于testTCHAR 类型包含托管引用,因此您不能将指针用作签名的一部分(您没有这样做),而且按值传递它也没有意义(这就是运行时生成的原因你看到的错误)。

    您需要更改您的签名,以便将指针传递给本机方法:

    public delegate void testChar(IntPtr data);
    public unsafe static extern IntPtr TestCallBackChar([MarshalAs(UnmanagedType.FunctionPtr)] testChar call);
    

    调用时,您需要将结构显式编组为托管等效项(反之亦然):

    testChar tChar =
        (inputPtr) =>
        {
            testTCHAR input = (testTCHAR)Marshal.PtrToStructure(inputPtr, typeof(testTCHAR));
        };
    
    IntPtr returnedPtr = TestCallBackChar(tChar);
    testTCHAR returned = (testTCHAR)Marshal.PtrToStructure(returnedPtr, typeof(testTCHAR));
    

    另外,我猜 C++ 和 C# 签名和方法名称不匹配。

    【讨论】:

    • 它有效,非常感谢@Daniel Balas。
    猜你喜欢
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    相关资源
    最近更新 更多