分析DLL函数并编写程序调用它的问题
首先,按照两位评论者的建议,研究一下 ArcCompress 方法的语义。如果它真的返回一个 C 文件指针,你会在 C# 中用它做什么??不多,我想。您可能无法在那里关闭文件。
但无论如何,这里有两种从 C# 调用 ArcCompress 方法的可能性。作为一个小测试,首先是一个虚构的简单 ArcCompress C dll 函数,作为测试工具来查看指针是否正确编组。该函数必须声明为 extern "C" 以避免名称修改。
//Next line is from the header file
//#define PINVOKE_DLL_API __declspec(dllexport)
PINVOKE_DLL_API FILE* __cdecl ArcCompress(char* a1, char* a2, int a3)
{
a1[2] = 0xfe;
FILE* f = fopen("D:\\testfile.bin", "wb+");
fwrite(a1, a3, 1, f);
return f;
}
这个简单的函数接受您的字节数组,修改一个字节并将其写入文件,返回打开文件的文件指针。这里有两种从 C# 调用这个函数的可能性(在我的例子中,dll 被命名为“pinvoke_dll.dll”而不是“Arc.dll”):
缓冲区参数是普通引用,这里没有什么特别之处。但是,应该检查 .NET 垃圾收集器是否可能出现问题。假定数组已被初始化。
[DllImport("pinvoke_dll.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr ArcCompress(ref byte a, ref byte b, Int32 c); private void button1_Click(object sender, EventArgs e) { IntPtr f = ArcCompress(ref a[0], ref b[0], a.Length ); }缓冲区参数是 C# 指针,就像普通的 C 指针一样。在这种情况下,您必须将您的方法标记为“不安全”(并选中项目属性中的相应复选框),并将指针标记为固定的,从而通知垃圾收集器不要触摸它们。
public unsafe partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("pinvoke_dll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ArcCompress(byte* p1, byte* p2, Int32 c);
byte[] a = new byte[10]{1,2,3,4,5,6,7,8,9,0};
byte[] b = new byte[10]{0,9,8,7,6,5,4,3,2,1};
private void button1_Click(object sender, EventArgs e)
{
fixed (byte* p1 = &a[0], p2 = &b[0])
{
IntPtr f = ArcCompress(p1, p2, a.Length);
}
}
}
顺便说一句,通过这种方式,您可以像在 C 中一样在 C# 中应用指针算术。您必须记住,您处于不安全的上下文中,就像在 C 或 C++ 中一样。
玩得开心!

