我们在Borland Delphi中编写和编译了32位库。该库由各种其他项目引用,包括IIS中托管的WCF Web服务。使用x86选项编译Web服务,一切都可以在32位计算机上正常工作。但是,在我们的64位服务器上,调用32位Delphi库时服务失败。我们的一些客户甚至遇到32位.NET Forms调用64位机器上的库的问题;虽然我们无法复制该特定问题。
那么,有没有人知道为什么在64位计算机上调用非.NET 32位库时,使用32位选项编译的.NET代码仍会失败?
答案 0 :(得分:0)
嗯,只是一个疯狂的猜测:)
您是否有多个流程进行交互?这些进程是否尝试写入/读取受保护的文件夹(例如%PROGRAMFILES%,%WINDIR%)? (即,这些进程是否使用IPC等文件夹中的文件?)
由于64位Windows会将写入重定向到32位应用程序的此类文件夹(在每个用户基础上),如果进程在不同的用户凭据下运行,这些进程可能无法找到由其他进程创建的文件。
答案 1 :(得分:0)
我猜你在.NET这边定义方法的入口点是这样的吗?
internal static class Delphi
{
[DllImport("delphi32bitlibrary.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool Encrypt(
IntPtr parameter1,
string parameter2,
out string parameter3);
}
然后你以类似的方式在某处召唤它?
string encryptedString;
Delphi.Encrypt(IntPtr.Zero, "test", out encryptedString);
如果是这种情况(您的里程可能会因实际情况而有所不同),您可以这样重写:
string encryptedString;
try
{
Delphi.Encrypt(IntPtr.Zero, "test", out encryptedString);
}
catch (Exception ex)
{
EventLog log = new EventLog();
log.WriteEntry(ex.Message + "\n" + ex.StackTrace, EventLogEntryType.Error);
}
这应该在计算机的事件日志中详细解释调用32位文件时发生的情况。从那里,你(可能还有我们)可以得到一些关于可能失败的好证据。
答案 2 :(得分:0)
堆腐败!显然有一个名为HeapEnableTerminationOnCorruption的标志,以前没有默认启用。作为Windows Vista中的新功能,IIS工作进程在检测到堆损坏时终止。所以,它只是在我们的独立应用程序和我们的32位Windows XP机器上工作,实际上它只是忽略了错误。
为了解决这个问题,我们更改了调用Delphi库的代码以使用IntPtrs并使用out参数传回数据。例如:
public string CallDLL(string sTest)
{
string s = "";
IntPtr p1 = Marshal.StringToHGlobalAnsi(sTest);
s = Marshal.PtrToStringAnsi(p1);
if (p1 != IntPtr.Zero)
{
Class1.TestDLL(out p1);
s = Marshal.PtrToStringAnsi(p1);
}
Marshal.FreeCoTaskMem(p1);
return s;
}
希望这可以帮助任何有同样问题的人。