返回类型不匹配的Visual C ++

时间:2012-12-20 21:23:10

标签: c# visual-studio-2010 visual-c++ types bytearray

我在Visual C ++中有以下返回类型:

extern "C" __declspec(dllexport) unsigned char* _cdecl 
                                          getname(LPCTSTR Track1, int len)

我编写了以下代码,以便在C#中获得正确的unsigned char*值:

[DllImport(_dllLocation, CallingConvention = CallingConvention.Cdecl)]
 public static extern byte[] getname(string track1, int len);

我使用以下代码从另一个.cs文件调用上述方法:

string track = "hello12345"; 
byte[] name = UnsafeNativeMethods.getname(track, 160);

请告诉我这里做错了什么,请检查参数数据类型,即LPCTSTRstring

unsigned char*是否等同于byte[]。如果是这样,那么为什么我在C#文件中得到错误的值,在C ++中它是正确的。

编辑:

在通过评论提出一些建议后,我已将byte name更改为byte[] name,但它显示以下异常:

A first chance exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in DecryptionWS.dll
A first chance exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in DecryptionWS.dll
A first chance exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in   System.ServiceModel.dll
A first chance exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in System.ServiceModel.dll

1 个答案:

答案 0 :(得分:2)

unsigned char*byte[]并不完全等效。 unsigned char*是指向字节的指针,但byte[]是一个字节数组,其中已知长度unsigned char*没有已知的长度。 .Net marshaller无法直接从unsigned char*封送到byte[],因为它不知道缓冲区的长度。

因此您必须手动编组返回值:

  1. 更改p / Invoke函数定义以返回IntPtr(这是一个通用指针值)`
  2. 使用Marhsal.CopyIntPtr复制到字节数组。
  3. 〔实施例:

    [DllImport(_dllLocation, CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr getname(string track1, int len);
    
    
    string track = "hello12345"; 
    IntPtr namePtr = UnsafeNativeMethods.getname(track, 160);
    Byte[] name = new Byte[/* some size here - it is not clear how*/];
    Marshal.Copy(namePtr, name, 0, name.Length);