gpt4 book ai didi

C# 互操作 Delphi DLL

转载 作者:行者123 更新时间:2023-12-03 12:15:24 28 4
gpt4 key购买 nike

我有一个第三方 DLL 用 Delphi“a.dll”(无源代码)编写。

这个 DLL 有一个带有这个签名的方法。

function GetAny(pFileName: String): String;

我无法从 c# 进行互操作调用,因为“字符串类型”在 delphi 中具有私有(private)访问权限。

因此,在 delphi 中构建另一个 DLL 来包装该调用。

德尔福。
function GetAny(pFileName: String): String; external 'a.dll'

function GetWrapper(url : PChar) : PChar; stdcall;
begin
Result := PChar(GetAny(url)); // I need avoid this String allocation, is throwing a exception.
end;

C#。
[DllImport("wrapper.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern IntPtr GetWrapper(String url);

在“GetWrapper”中,我调用了外部“GetAny”,结果是好的(在delphi中我可以调试),但是在我把这个结果返回到c#端之前,它抛出了一个异常。
IntPtr test = GetWrapper("a");
String result = Marshal.PtrToStringAnsi(test);

最佳答案

您的包装 DLL 也不能调用 GetAny,因为字符串是托管的 Delphi 类型,不能跨模块边界传递。

问题是 GetAny 的返回值在一个模块中分配并在不同的模块中释放。它在实现 GetAny 的 DLL 中分配,并在调用 GetAny 的 DLL 中释放。由于这两个 DLL 使用不同的内存管理器,因此您最终会尝试释放分配在不同堆上的内存。

如果可以说服实现 GetAny 的 DLL 共享内存管理器,那么您可以轻松解决该问题。

我确实质疑你提出的事实。就目前而言,除非 DLL 设计为与 ShareMem 一起使用,否则永远无法安全地调用该函数。

如果你准备泄漏内存,你可以试试这个:

德尔福

function GetAny(pFileName: string): PChar; external 'a.dll'

procedure GetWrapper(url: PChar; out value: WideString); stdcall;
var
P: PChar;
begin
P := GetAny(url);
if Assigned(P) then
Value := P
else
Value := '';
end;

C#
[DllImport("wrapper.dll"]
public static extern void GetWrapper(
string url,
[MarshalAs(UnmanagedType.BStr)]
out string value
);

关于C# 互操作 Delphi DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18425243/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com