Native DLL - C#
本文关键字:DLL Native | 更新日期: 2023-09-27 18:16:23
我在Delphi中编写了本机DLL库。我想从c#中引用这个库并获得返回的字符串。
函数function GetCode (aUser,aPassword: PAnsiChar): PAnsiChar; stdcall;
c#代码[DllImport("C:''library.dll", CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
private static extern String GetCode([MarshalAs(UnmanagedType.LPStr)]string aUser, [MarshalAs(UnmanagedType.LPStr)]string aPassword);
public String getCode(String login, String password) {
return GetCode(login, password);
}
尝试调用函数应用程序退出,代码为-1073740940 (0xc0000374).
你有这方面的经验吗?谢谢你的帮助如果返回值为string
,则编组程序负责释放返回的字符串。它通过调用CoTaskMemFree
来实现。毫无疑问,您的字符串没有在COM堆上分配。由此产生错误,即STATUS_HEAP_CORRUPTION
的NTSTATUS
错误码。
你的p/调用应该返回一个IntPtr
来避免这种情况:
[DllImport("C:''library.dll", CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
private static extern IntPtr GetCode(string aUser, string aPassword);
要获取字符串,将返回值传递给Marshal.PtrToStringAnsi
。
public string getCode(string login, string password)
{
IntPtr retval = GetCode(login, password);
string result = Marshal.PtrToStringAnsi(retval);
// how do we deallocate retval
return result;
}
还要注意,我删除了多余的MarshalAs
属性。CharSet.Ansi
负责输入参数的编组。
您仍然需要弄清楚如何释放返回的内存。我们不知道它是如何分配的。您需要联系Delphi代码的开发人员,或者阅读源代码。如果使用了本机Delphi堆,请不要感到惊讶,这会使您陷入困境。通过调用CoTaskMemAlloc
来使用COM堆实际上是一个不错的选择,然后您的原始p/invoke返回值string
就可以了。
其他选项包括导出deallocator或要求调用者分配缓冲区。网上有很多关于如何实现各种选项的例子。