gpt4 book ai didi

c# - 从 C# 调用 dll 中的 Delphi 方法

转载 作者:太空狗 更新时间:2023-10-29 22:22:58 24 4
gpt4 key购买 nike

我正在尝试调用具有以下签名的 Delphi DLL 中的方法:

 function SMap4Ovr(const OverFileName       : ShortString    ;
const Aclay : Integer ;
const Acarbon : Double ;
out errstr : ShortString): WordBool;

我在 C# 中使用以下导入:

        [DllImport("SMap.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern bool SMap4Ovr(
string OverFileName,
int Aclay,
double Acarbon,
out string errstr
);

但我遇到了 AccessViolationException。

我似乎能够调用 DLL 中的几个更简单的方法,这些方法具有字符串参数但没有整数或 double 。

我也尝试过使用 CallingConvention = CallingConvention.Cdecl 但这给了我同样的错误。

最佳答案

在编写互操作代码时,接口(interface)的两端在各个方面都匹配是至关重要的。以下是您必须让双方达成一致的主要问题:

  1. 调用约定。
  2. 参数列表。
  3. 参数类型和语义。

第一个观察结果是您的调用约定不匹配。您在 Delphi 端有 register,在 C# 端有 stdcall。 Delphi register 约定是 Delphi 私有(private)的,因此您应该使用 stdcall

其次,你的字符串参数类型不匹配。 Delphi shortstring 是一种数据类型,在 Delphi 2 发布时成为遗留物,应该被视为上个世纪的遗物。它从来都不是有效的互操作类型,并且 p/invoke 框架中没有任何东西可以用来匹配它。虽然您可以尝试手动进行编码,但如果有简单的解决方案可用,则不需要做大量工作。你应该试着忘记所有关于 shortstring 的事情。

您需要使用接口(interface)双方都可以使用的字符串类型。您可以使用以 null 结尾的 C 字符串,但更好和更简单的选择是 COM BSTR,它在 Delphi 中是 WideString

所以,最终的结果如下。

德尔福

function SMap4Ovr(
OverFileName: WideString;
Aclay: Integer;
Acarbon: Double;
out errstr: WideString
): WordBool; stdcall;

C#

[DllImport("SMap.dll")]
public static extern bool SMap4Ovr(
[MarshalAs(UnmanagedType.BStr)]
string OverFileName,
int Aclay,
double Acarbon,
[MarshalAs(UnmanagedType.BStr)]
out string errstr
);

我没有在 DllImport 上指定调用约定,因为默认是 stdcall。如果您愿意,可以明确说明这一点。

使用 WideString 时要小心 don't attempt to use it as a return value .因为 Delphi 对返回值使用非标准语义,所以您只能使用适合寄存器的简单类型作为返回值。

关于c# - 从 C# 调用 dll 中的 Delphi 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16601423/

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