我有很多遗留代码,我目前使用过时的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项目中简单地提取我需要的代码?
答案 0 :(得分:1)
据我所知,DllImport仅适用于与.Net应用程序字大小相同的非托管dll。例如。 64位.Net应用程序中的DllImport只能在64位dll上运行,32位.Net应用程序只能加载32位dll等。我也认为不可能让DllImport加载16 -bit dll。
我想到了一些可能的解决方案:
史蒂夫提到使用COM。如果你想把你的.Net应用程序保存在64位,你可以用COM来做这样的工作:将你的C代码重新编译为32位dll,使用.Net为该dll写一个32位的COM包装器然后让你的64位.Net应用程序调用32位COM服务器,然后调用你的32位dll。 MSDN在interoperating with unmanaged code上有一些信息。
将您的dll和.Net应用程序编译为32位。 DllImport应该能够加载dll。 (您可能需要在extern "C"
中包装C代码,并在dll上运行TDUMP或DUMPBIN实用程序以检查名称是否已损坏。)
如果您拥有所有C源代码,您是否可以忘记Borland编译器并使用Visual Studio的C ++编译器构建代码?
答案 1 :(得分:0)
.net将调用COM并且可以非常愉快地调用COM(对于适当的COM调整值happy),所以如果旧的本机代码提供了合适的COM接口,您可以尝试直接使用它(但是需要使用32位版本。
如果您不需要在一个进程中处理所有内容,则另一种方法是将代码构建为C ++ / CLI程序集和Borland DLL(如果您有.c
个文件,那么您将只需{。1}}。.cpp
文件中的#include
文件。{/ p>
答案 2 :(得分:0)
如果您同时使用32位.NET和32位C-DLL,则应该没有问题。我几乎100%肯定你不能轻易地从32位应用程序调用16位代码(虽然我认为我已经看到了这样做的解决方案 - 这里出现了“thunking”这个词?)。
如果.NET和DLL都是32位,那么你应该对上面所做的事情没有问题,但是我记得有一些关于Borland DLL的东西使得它们与其他“普通”C-DLL不兼容。 / p>
史蒂夫吉尔罕关于COM的回答可以忽略我认为,因为COM既不是必要的,也不是你选择的好选择。