0

我有很多遗留代码,我目前使用旧版 Borland C++ 3.0 进行编译。

这段代码中有一个规则引擎,我想在 C# .NET 应用程序中提取和使用它。

问题是,如果我将规则引擎提取到它自己的 DLL 中,我希望能够从我没有时间移植的现有遗留代码和 C# .NET 应用程序中调用这个 DLL。

如果我使用旧的 Borland 编译器构建 DLL,我不知道如何从 C# .Net 项目中引用它。DllImport 失败并出现 BadImageFormatException。用谷歌搜索这个异常表明大多数人在编译一个支持 64 位的程序并将 32 位的东西加载到其中时都会遇到这个问题。问题是,我有理由确定我正在生成 16 位 DLL,而且似乎没有解决方法。

我可以下载具有 32 位编译器和链接器的较新的 Borland 5 编译器,但我仍然遇到同样的问题,所以也许我也有问题。

这是我的 C# 调用代码

[DllImport( "C:\\NSDB\\BorlandDLL\\BorlandDLL.dll", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl )]
static extern int Version();

public frmHelpAbout()
{
    InitializeComponent();

    lblIssueVersion.Text =  + Version();
}

这是我的 DLL 代码

int Version()
{
    return 93;
}

我的编译器标志和链接器标志都是完全的猜测 - 我希望这是我的主要问题

我注意到我的 DLL 代码没有用 __stdcall、extern "C" 之类的东西装饰。我似乎找不到 Borland C++ 3.0 理解的正确符号集来强制我需要的那种调用约定。

所以,问题:

1) DllImport 是否能够使用从 Borland C++ 3.0 生成的代码 1b) 如果不能,我是否能够移植代码以使用 Borland C+ 5.5.1 编译器,并让 DllImport 使用它?

2)我可以扭转这个问题吗?如果我将 DLL 代码移植到 .NET 中,我是否能够让旧的 Borland 代码调用它?

3) 你有任何其他创新的解决方案可以让我从这个旧的 Borland 项目中简单地提取我需要的代码吗?

4

3 回答 3

2

据我所知,DllImport 仅适用于与 .Net 应用程序字长相同的非托管 dll。例如,64 位 .Net 应用程序中的 DllImport 只能在 64 位 dll 上工作,32 位 .Net 应用程序只能加载 32 位 dll 等。我也不认为可以让 DllImport 加载16 位 dll。

我想到了一些可能的解决方案:

  1. 史蒂夫提到使用 COM。如果您想将 .Net 应用程序保持在 64 位,您可以使用 COM 使事情像这样工作:将您的 C 代码重新编译为 32 位 dll,使用 .Net 为该 dll 编写 32 位 COM 包装器,然后让您的 64 位 .Net 应用程序调用 32 位 COM 服务器,该服务器又会调用您的 32 位 dll。MSDN 有一些关于与非托管代码互操作的信息。

  2. 为 32 位编译您的 dll 和 .Net 应用程序。然后 DllImport 应该能够加载 dll。(您可能需要将 C 代码包装在 .dll 中extern "C",并在 dll 上运行 TDUMP 或 DUMPBIN 实用程序以检查名称修改)。

  3. 如果您拥有所有 C 源代码,您是否可以忘记 Borland 编译器并使用 Visual Studio 的 C++ 编译器构建代码?

于 2009-09-24T14:49:16.887 回答
0

.net 将调用 COM 并且可以很高兴地被称为 COM(对于一个适当的 COM 调整值快乐),所以如果旧的本机代码提供了一个合适的 COM 接口,你可以尝试直接使用它(但这需要使用32 位版本)。

如果您不需要所有内容都在一个进程中,另一种方法是将代码构建为 C++/CLI 程序集和 Borland DLL(如果您有.c文件,那么您将需要.cpp#include包含文件的.c文件) .net 项目)。

于 2009-09-24T13:28:24.397 回答
0

如果您同时使用 32 位 .NET 和 32 位 C-DLL,则应该没有问题。我几乎 100% 确定您不能轻易地从 32 位应用程序调用 16 位代码(尽管我认为我已经看到了这样做的解决方案——“thunking”这个词出现在这里?)。

如果 .NET 和 DLL 都是 32 位的,那么您应该可以接受上面的操作,但我记得 Borland DLL 有一些东西使它们与其他“普通”C-DLL 不兼容。

我认为 Steve Gilham 关于 COM 的回答可以忽略,因为在你的情况下,COM 既不是必要的,也不是一个好的选择。

于 2009-09-24T14:31:27.203 回答