0

我有 BCB5 dll 方法:

extern "C" void __declspec(dllexport) __stdcall SM(TDataSource *DS) {

 TForm *form = new TForm(Application);
 form->Width = 300;
 form->Height = 300;
 form->Name = "frm";

 TDBGrid *grd = new TDBGrid(form);
 grd->Parent = form;
 grd->Name = "grd";
 grd->Align = alClient;
 grd->DataSource = DS;

 form->ShowModal();

}

当我从 C++ builder 5 应用程序调用此方法时,它工作正常。

try {
 typedef void __declspec(dllexport) __stdcall SM(TDataSource *DS);
 SM *Upload;
 HINSTANCE hDll = LoadLibrary("main.dll");

 Upload = (SM*) GetProcAddress(hDll,"SM");
 Upload(DataSource1);
 FreeLibrary(hDll);

}
catch (Exception *ex) {
  ShowMessage(ex->Message);
}

但是,如果我尝试从 C++ XE 5 应用程序调用此方法,我会遇到访问冲突。

有没有办法解决XE 5应用程序到BCB 5 dll的数据传输问题而无需在XE5中重新编译dll?

4

1 回答 1

0

像您正在做的那样在 DLL 边界上传递/使用 RTL/VCL 对象是不安全的,除非 EXE 和 DLL 都是在启用运行时包的情况下编译的,以便它们共享相同 RTL 和 VCL 框架的公共实例(但是你必须使用您的应用程序部署 RTL/VCL BPL 二进制文件)。

您的 DLL 在 XE5 中不起作用,因为 DLL 需要TDataSource组件的 BCB5 版本,而不是 XE5 版本。不,它们不兼容,因为它们具有不同的内存布局和依赖关系。

所以你的选择是:

  1. 在 XE5 中重新编译 DLL,并承担通过TDataSourceDLL 边界通常不安全的风险,除非您启用运行时包。

  2. 将 DLL 重写为运行时包 (BPL)。TDataSource然后在 EXE 和 DLL 之间传递是安全的。但是,运行时包是特定于版本的,因此如果您需要继续使用 BCB5 和 XE5 中的代码,则需要编译单独的 BPL。

  3. 重新编写 DLL 以不通过TDataSourceDLL 边界开始。找出另一种在 EXE 和 DLL 之间交换数据的互操作安全方式。

于 2017-06-15T17:46:39.243 回答