Dllimport 无法导入旧的 Borland dll

发布于 2024-08-05 05:27:51 字数 1194 浏览 1 评论 0原文

我有很多遗留代码,目前使用 Borland C++ 3.0 的过时安装进行编译。

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

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

如果我使用旧的 Borland 编译器构建 DLL,我无法弄清楚如何从 C# .Net 项目引用它。 DllImport 失败并出现 BadImageFormatException。谷歌搜索此异常表明大多数人在编译 64 位功能的程序并向其中加载 32 位程序时都会遇到此问题。问题是,我相当确定我正在生成 16 位 DLL,并且似乎没有解决方法。

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

这是我的 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 项目中提取我需要的代码?

I have a lot of legacy code which I currently compile using an antiquated install of Borland C++ 3.0.

There's a rules engine in this code that I'd like to extract and use in a C# .NET application.

The thing is, if I extract the rules engine into it's own DLL, I want to be able to call this DLL from both the existing legacy code which I don't have time to port, and from the C# .NET app.

If I build a DLL using the old Borland compiler, I can't work out how to reference it from the C# .Net project. DllImport fails with a BadImageFormatException. Googling on this exception indicates that most people encounter this problem when compiling a 64-bit capable program and loading something 32-bit into it. Thing is, I'm reasonably sure I'm generating 16-bit DLLs, and there seems to be no workaround for this.

I can download the newer Borland 5 compiler which has a 32-bit compiler and linker, but I'm still getting the same issue, so perhaps I have something wrong there too.

This is my C# calling code

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

public frmHelpAbout()
{
    InitializeComponent();

    lblIssueVersion.Text =  + Version();
}

This is my DLL code

int Version()
{
    return 93;
}

My compiler flags and linker flags are all complete guesswork - I'm hoping that this is my main problem

I noticed my DLL code is not decorated with anything like __stdcall, extern "C" or whatever. I can't seem to find the correct set of symbols that Borland C++ 3.0 understands to force the kind of calling conventions I need.

So, the questions:

1) Will DllImport ever be able to work with code generated from Borland C++ 3.0
1b) If not, will I be able to port the code to work with the Borland C+ 5.5.1 compiler, and get DllImport to work with that?

2) Can I turn the problem around? If I ported the DLL code into .NET, would I ever be able to get the old Borland code to call it?

3) Do you have any other innovative solutions that will let me simply extract the code I need from this old Borland project?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

幽蝶幻影 2024-08-12 05:27:51

据我所知,DllImport 仅适用于与 .Net 应用程序字大小相同的非托管 dll。例如,64 位 .Net 应用程序中的 DllImport 仅适用于 64 位 dll,32 位 .Net 应用程序只能加载 32 位 dll,等等。我也不认为可以让 DllImport 加载16 位动态链接库。

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

  1. Steve 提到使用 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 代码包装在 extern "C" 中,并在 dll 上运行 TDUMP 或 DUMPBIN 实用程序来检查名称修改)。

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

As far as I know, DllImport will only work for unmanaged dlls that are the same word size as the .Net app. E.g. DllImport in a 64-bit .Net app will only work on 64-bit dlls, a 32-bit .Net app can only load 32-bit dlls, etc. I also don't think it's possible to get DllImport to load a 16-bit dll.

Some possible solutions come to mind:

  1. Steve mentioned using COM. If you want to keep your .Net app in 64-bit, you could use COM to make things work like this: recompile your C code as a 32-bit dll, use .Net to write a 32-bit COM wrapper for that dll, then have your 64-bit .Net app call the 32-bit COM server, which would in turn call your 32-bit dll. MSDN has some info on interoperating with unmanaged code.

  2. Compile both your dll and .Net app for 32-bits. DllImport should be able to load the dll then. (You might need to wrap your C code in extern "C", and run the TDUMP or DUMPBIN utilities on the dll to check for name mangling).

  3. If you have all of the C source code, can you just forget about the Borland compiler and build the code with Visual Studio's C++ compiler?

jJeQQOZ5 2024-08-12 05:27:51

.net 将调用 COM 并且可以非常愉快地调用 COM(对于适当的 COM 调整的 happy 值),因此如果旧的本机代码提供了合适的 COM 接口,您可以尝试直接使用它(但这需要使用32 位版本)。

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

.net will call COM and can be called as COM quite happily (for a suitably COM-adjusted value of happy), so if the old native code provides a suitable COM interface you could try using that directly (but that would need to be using a 32-bit build).

If you don't need everything to be in the one process, an alternative approach would be to build the code as a C++/CLI assembly and as a Borland DLL (if you have .c files, then you will need .cpp files that just #include the .c file in the .net project).

装纯掩盖桑 2024-08-12 05:27:51

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

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

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

If you're using both 32bit .NET and 32bit C-DLL you should not have a problem. I'm almost 100% sure that you can not call 16bit code from a 32bit application easily (though I think I've seen solutions that do that - the word "thunking" comes to my mind here?).

If both .NET and DLL are 32bit, you should be alright with what you're doing above, but I remember that there was something about Borland DLLs which made them kind of incompatible with other "normal" C-DLLs.

The answer by Steve Gilham about COM can be ignored I think, as COM is neither necessary nor a good option in your case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文