我在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);
请告诉我这里做错了什么,请检查参数数据类型,即LPCTSTR
和string
。
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
答案 0 :(得分:2)
unsigned char*
和byte[]
并不完全等效。 unsigned char*
是指向字节的指针,但byte[]
是一个字节数组,其中已知长度。 unsigned char*
没有已知的长度。 .Net marshaller无法直接从unsigned char*
封送到byte[]
,因为它不知道缓冲区的长度。
因此您必须手动编组返回值:
IntPtr
(这是一个通用指针值)`IntPtr
复制到字节数组。〔实施例:
[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);