0

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

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

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

[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 namebyte[] 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
4

1 回答 1

2

unsigned char*并且byte[]不完全等价。Anunsigned char*是指向字节的指针,但 a是已知长度byte[]的字节数组。An没有已知的长度。.Net marshaller 不能直接从a 编组到 a ,因为它不知道缓冲区的长度。unsigned char*unsigned char*byte[]

因此,您将不得不手动编组返回值:

  1. 更改您的 p/Invoke 函数定义以返回一个IntPtr(即通用指针值)`
  2. 使用Marhsal.Copy从 复制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);
于 2012-12-20T21:57:28.120 回答