unsigned char ** 在 c# 中等效,并且必须将返回值写入文件

Posted

技术标签:

【中文标题】unsigned char ** 在 c# 中等效,并且必须将返回值写入文件【英文标题】:unsigned char ** equivalent in c# and have to write the return value in a file 【发布时间】:2012-12-21 13:27:10 【问题描述】:

我必须调用一个win32 dll函数

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

我需要用 c# 包装成

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

我从一个 c# 应用程序中将它称为

int arg1;
IntPtr arg2 = IntPtr.Zero;
IntPtr arg3 = IntPtr.Zero;
func1(arg1,out arg2,out arg3);

在 C# 包装器中声明的函数以及在 C# 测试应用程序中调用的函数是否正确? 现在我需要将 arg2 存储在文本文件中。如何做到这一点。

从汉斯那里得到答案,我用

将它写在一个文件中
System.IO.StreamWriter(@Application.StartupPath + "\\Filename.txt");
file.WriteLine(arg2);
file.Close();

【问题讨论】:

最后一个参数是ref int。您不太可能调用此函数,字符串需要在使用 Marshal.PtrToStringAnsi() 转换后释放。不能,这会泄漏内存。 @HansPassant 我在 dll 中有一个空闲函数来清除内存 【参考方案1】:

我在dll中有一个空闲的函数来清除内存

那么你就有机会完成这项工作。函数声明应如下所示:

[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int func1(int arg1, out IntPtr arg2, ref int arg3);

你会这样称呼它:

IntPtr ptr = IntPtr.Zero;
int dunno = 99;
string result = null;

int retval = func1(42, out ptr, ref dunno);
if (retval == success) 
    result = Marshal.PtrToStringAnsi(ptr);
    // etc...

if (ptr != IntPtr.Zero) func1free(ptr);

其中“func1free”是释放字符串的其他未记录的函数。

【讨论】:

这行得通,但第三个参数 arg3 不是对 arg2 的引用。 arg2 和 arg3 是输出值。 arg2 是缓冲区值,arg3 是缓冲区值的长度。【参考方案2】:

您可能需要使用MarshalAs 属性,例如:

public static extern int func1(int arg1, [MarshalAs(UnmanagedType.LPStr)] string arg2, IntPtr arg3);

在此处查看文档:

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute.aspx

【讨论】:

感谢您的回复。我第一次忘记提到我在 arg2 中获取输出值。现在我得到了输出,但我在 arg2 中缺少一些字节

以上是关于unsigned char ** 在 c# 中等效,并且必须将返回值写入文件的主要内容,如果未能解决你的问题,请参考以下文章

C# PInvoke 传递出 unsigned char*

如何将带有 unsigned char* 的结构从 C# 传递到 C++?

Swig:将 std::vector<unsigned char> 传递给从 c++ 生成的 c# 函数

将 System::String^ 转换为 unsigned char*

在C语言中,unsigned char是啥类型

unsigned char 与 char 有啥却别?何时适用