【发布时间】:2019-08-05 21:30:49
【问题描述】:
我有一个 C# 应用程序 (VS 2017 .Net 4.6.1),它将字符串传递给处理输入和返回输出的 Delphi DLL (Delphi 10.2)。
我收到一个 FaultExecutionEngineError “此错误的常见来源包括 COM-interop 或 PInvoke 的用户封送错误”。
我有几个问题:
如果我的 Delphi DLL 是用 IMAGE_FILE_LARGE_ADDRESS_AWARE 编译的,我的 c# App 是否也需要用 editbin /largeaddressaware 编译?
我的 Delphi DLL 加载子 DLL 会导致 FaultExecutionEngineError 吗?在我的测试中,除了初始启动之外,我实际上并没有调用子 DLL 中的任何内容。
有没有工具可以在 Delphi 中调试这些?
德尔福:
procedure Go(Inputs : WideString; var Rates : WideString); stdcall;
begin
Rates := Inputs + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
end;
c#
[DllImport("DelphiDLL.dll",
CharSet = CharSet.Unicode,
EntryPoint = "LoadLibraries")]
public static extern void _LoadLiabraries(
out int res);
[DllImport("DelphiDLL.dll",
CharSet = CharSet.Unicode,
EntryPoint = "Go")]
public static extern void _Go(
[MarshalAs(UnmanagedType.BStr)]
string Inputs,
[MarshalAs(UnmanagedType.BStr)]
out string Outputs);
public static string CallGo(string Inputs) {
string outputs;
_Go(Risk, out outputs);
return outputs;
}
如果我运行这段代码:
{
string inputs = "Test Input";
int i = 0;
do {
string output = CallGo(inputs);
Console.WriteLine(String.Format("{0} {1} {2}", i, inputs, output)
} while (i++ < 10000)
}
我没有收到消息,但如果我运行这个:
{
int llres = 0;
_LoadLibraries(llres);
string inputs = "Test Input";
int i = 0;
do {
string output = CallGo(inputs);
Console.WriteLine(String.Format("{0} {1} {2}", i, inputs, output)
} while (i++ < 10000);
}
在尝试 N 次后我得到了错误。尝试次数在尝试之间保持一致。如果我更改代码,成功尝试的次数就会改变。
【问题讨论】:
-
我只是尝试了这种传递和接收整数而不是字符串的方法,但仍然出现错误,尽管这是在对 Delphi DLL 进行了数千次调用之后
-
我也看过那个和其他的。我尝试了很多我在这里找到的不同方法。他们都为许多电话工作,然后失败。我尝试的最后一件事是传递和接收一个整数。在多次调用 dll 后它失败了。当我跳过加载其他 dll 时,它们都没有失败。我之前没有提到的可能导致问题的一件事是 dll 使用了 fastmm。也许是 fastmm 内存管理导致了问题。
-
大地址感知是一个进程属性。用它标记 dll 毫无意义。您的问题似乎与 _LoadLiabraries 相关,但我们看不到它的作用。
-
感谢 David,这是我对大型地址感知的印象,但我想确认情况确实如此。我会看看我能做些什么来放置 _LoadLibraries 代码。