等价于c#中的无符号字符*

本文关键字:字符 无符号 等价于 | 更新日期: 2023-09-27 17:49:20

可能重复:
无符号字符**在c#中等效,并且必须将返回值写入文件

我必须调用一个win32 dll函数

int func1(int arg1, unsigned char *arg2, int *arg3);

我把包装的c#写成

public extern int fuc1(int arg1, out IntPtr arg2, out IntPtr arg3);

arg2必须分配2048个字节并将其发送到win32 dll。我将得到arg2和arg3作为输出。

我如何在c测试应用程序和c包装器中声明。我做得对吗?

等价于c#中的无符号字符*

C#中的

字节是无符号的8位整数。byte[]是它们的数组。要获取指向此数组的指针,请使用:

 var myArray = new byte[2048];
 fixed(byte* arg2 = myArray)
 {
      // use arg2
 }

或:

 var myArray = new byte[2048];
 GCHandle pinnedRawData = GCHandle.Alloc(myArray, GCHandleType.Pinned);
 try
 {  
    // Get the address of the data array
    IntPtr pinnedRawDataPtr = pinnedRawData.AddrOfPinnedObject();
 }
 finally
 {
    // must explicitly release
    pinnedRawData.Free(); 
 } 

或者,如果被调用的函数不会缓存指向数组的指针,您可以简单地执行以下操作:

 public static extern int fuc1(int arg1, [In,Out] byte[] arg2, ref int arg3);
 var arg1 = 0;
 var arg2 = new byte[2048];
 int arg3 = 42; // If this value won't be used, you can skip initializing arg3 and mark arg3 as out instead of ref (of course, this is pedantic and extraneous, and C# shouldn't even have 'out' as a keyword)
 func1(arg1, arg2, ref arg3);

p/Invoke将自动将其固定。

类型的MSDN封送阵列

相关SO问题

在C#中这样声明函数:

[DllImport(@"MyDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int func1(
    int arg1, 
    StringBuilder arg2, 
    out int arg3
);

然后这样称呼它:

int arg1 = ...;
StringBuilder sb = new StringBuilder(2048);
int arg3;
int retVal = func1(arg1, sb, out arg3);
string arg2 = sb.ToString();

请注意,C#IntPtr与C int不匹配。您需要C#int来匹配它,因为IntPtr与指针大小相同,可以是32位,也可以是64位。但是int总是4个字节。

我假设您的DLL使用cdecl调用约定。如果您使用的是stdcall,则可以进行明显的更改。

我还假设您的数据实际上是文本数据。如果它只是一个普通的旧字节数组,那么代码就更简单了。

[DllImport(@"MyDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int func1(
    int arg1, 
    byte[] arg2, 
    out int arg3
);

然后打电话:

int arg1 = ...;
byte[] arg2 = new byte[2048];
int arg3;
int retVal = func1(arg1, arg2, out arg3);