Delphi DLL 可以在 C# 中被 PInvoked 和使用吗?
Posted
技术标签:
【中文标题】Delphi DLL 可以在 C# 中被 PInvoked 和使用吗?【英文标题】:Can a Delphi DLL be PInvoked and used in C#? 【发布时间】:2017-05-05 07:02:53 【问题描述】:我正在尝试迁移在 c++ builder 中构建的应用程序。由于时间限制,我们的客户希望我们导入 VCL 功能,而不是寻找 .net 等价物或创建新功能。
我尝试调用 rtl100.bpl 的 ExtractRelativePath 函数,该函数将 AnsiString 作为返回和参数。然后我使用 IntPtr 来传递和获取字符串,但是在调用 API 时会发生 AccessViolationException。
这是来自 rtl100.bpl 的函数原型
PACKAGE AnsiString __fastcall ExtractRelativePath(const AnsiString BasrName, AnsiString DestName);
这就是我对它的调用方式。
[DllImport("rtl100.bpl", EntryPoint = "@Sysutils@ExtractRelativePath$qqrx17System@AnsiString1", CallingConvention = CallingConvention.Cdecl)]
Internal static extern IntPtr ExtractRelativePath(IntPtr BaseName, IntPtr DestName);
当然,我将使用 thr marshal 类分配和解除分配 intptrs。
问题是,delphi 库真的可以用在 c# 中吗?它的大部分 API 使用 AnsiString,这是一个原生的 delphi 字符串。或者我们应该开始考虑使用 .net 函数?
谢谢
【问题讨论】:
您使用了错误的调用约定。但是,您似乎无法调用此 Delphi 函数,因为 .NET 不支持CallingConvention.FastCall
。
@Ðаn:如果 DLL 使用像 AnsiString
和 Delphi/C++Builder 的 fastcall
这样的类型,那么在 C++/CLI 中就无法编译甚至访问。它可以包装在 C++Builder 中,并改为使用原始类型 (POD) 类型,并且可以轻松导出,然后由 .NET 编组。但是如果这使用 AnsiString 很多,那么使用 DLL 可能根本没有意义。
见大卫赫弗南的回答。这根本不可行。 RTL100.BPL 是一个用 Delphi (Object Pascal) 编写的 DLL,并带有附加功能(或多或少像一个程序集),使其可以直接由 Delphi 和 C++Builder 直接使用和链接仅相同版本。 C++Builder 是我所知道的唯一可以直接链接到此类 BPL 的 C++。这是一个完整的运行时库,包含数百个函数,这些函数全部使用不兼容的 fastcall 调用约定并传递几个 Delphi/C++Builder 特定类型,这些类型在其他编译器/工具链中没有等效项。另请参阅 David 的第 3 点。
@Ðаn: 是的,你通常可以找到一种使用 Delphi 和/或 C++Builder DLL 的方法,但这不是一个普通的 DLL,它是一个 BPL,一个充满元数据的特殊 DLL使其直接 - 并且仅 - 可用于 Delphi(及其兄弟 C++Builder)。只有这两种语言才能真正使用这样的 BPL。它不打算用作普通的 DLL,它是特定版本的 Delphi 的运行时。
@dymanoid:实际上,即使它被支持,它在这里仍然无济于事。 C++Builder 的 __fastcall
与 MS 的 __fastcall
不同。它们都使用寄存器来传递参数,但不是相同的寄存器。 C++Builder的__fastcall
其实和Delphi默认的register
调用约定是一样的。
【参考方案1】:
你有多个问题:
-
Delphi RTL 使用其他工具链不支持的基于寄存器的调用约定。
AnsiString
是 Delphi 特有的类型,不能在其他工具链之间传递。
此特定函数分配调用者必须处理的堆内存。您的 C# 代码无法这样做。
我认为您可能需要重新调整客户的期望。你正在尝试的东西是不可行的。
【讨论】:
非常感谢@david,我知道当我看到它是 .bpl 时会很痛苦。我只是尝试包装这个 dll 而不考虑 .net 互操作的限制。猜猜我只是需要另一个开发人员的观点。再次感谢!以上是关于Delphi DLL 可以在 C# 中被 PInvoked 和使用吗?的主要内容,如果未能解决你的问题,请参考以下文章