无法封送“返回值”:无效的托管/非托管类型组合

时间:2017-07-24 14:53:13

标签: c# c++ marshalling

我在非托管库中有这个功能,我想在C#中调用它:

unsigned char __stdcall InitDev(unsigned char comport, long BaudRate)

这是在C#

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("*.dll", CallingConvention = CallingConvention.Cdecl,CharSet =CharSet.Auto)]
public static extern byte[] InitDev(byte[] comport, [Out]long BaudRate);

但是当我在C#中调用此函数时,我收到以下错误

  

“无法封送'返回值':托管/非托管类型组合无效。”

string COM = "COM3";
byte[] ptr = new byte[1];
try
{
    ptr = InitDev(Encoding.ASCII.GetBytes(COM), 9600);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

我是新手,如果提供了一些指导,我将能够解决这个问题

enter image description here

1 个答案:

答案 0 :(得分:2)

假设您的本机通话类似于unsigned char* InitDef(unsigned char*, long long &baudRate),那么您可能希望在IntPtr的位置使用unsigned char*。但首先,由于它是托管/非托管混合,你应该为输入和输出分配byte[]缓冲区:

byte[] pInBuffer = Encoding.ASCII.GetBytes("COM3");
// allocate unmanaged memory
IntPtr inputBuffer = Marshal.AllocHGlobal(pInBuffer.Length * sizeof(byte));
Marshal.Copy(pInBuffer, 0, inputBuffer, pInBuffer.Length);

// now your inputBuffer contains a native pointer to the `unsigned char*`
// and since your function returns a new pointer to some `unsigned char*`
// just retrieve it to IntPtr
IntPtr result = InitDev(inputBuffer, 9600);

// free your allocated memory
Marshal.FreeHGlobal(inputBuffer);

在此阶段,您的result包含InitDev返回的值。

InitDev功能的新定义

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("*.dll", CallingConvention = CallingConvention.Cdecl,CharSet =CharSet.Auto)]
public static extern IntPtr InitDev(IntPtr comport, [Out] long BaudRate);

您可以在此msdn page

找到所有必要的电话

编辑:
由于您的原生呼叫如下所示:extern unsigned char __stdcall InitDev(unsigned char comport,long BaudRate);
我猜测第一个参数只是"COMn"的最后一个数字(索引),因为unsigned char的最低可能值是0而COM的最低索引可以是0.

尝试使用此代码段:

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("*.dll", CallingConvention = CallingConvention.Cdecl,CharSet =CharSet.Auto)]
public static extern byte InitDev(byte comport, long BaudRate);

然后这样称呼它:

byte comIdx = 3;
byte result = InitDev(comIdx, 9600);
// byte should yield correct result now