32位应用程序在64位计算机上出现故障的非显而易见的原因是什么?

时间:2010-04-23 13:34:23

标签: .net wcf 32bit-64bit

我们在Borland Delphi中编写和编译了32位库。该库由各种其他项目引用,包括IIS中托管的WCF Web服务。使用x86选项编译Web服务,一切都可以在32位计算机上正常工作。但是,在我们的64位服务器上,调用32位Delphi库时服务失败。我们的一些客户甚至遇到32位.NET Forms调用64位机器上的库的问题;虽然我们无法复制该特定问题。

那么,有没有人知道为什么在64位计算机上调用非.NET 32位库时,使用32位选项编译的.NET代码仍会失败?

3 个答案:

答案 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;
    }

希望这可以帮助任何有同样问题的人。