C++ XE 5 应用程序和 C++ Builder 5 dll 兼容性

C++ XE 5 Application and C++ Builder 5 dll compatibility

我有 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 应用程序调用此方法,我会遇到访问冲突。

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

pass/use RTL/VCL 对象越过 DLL 边界是不安全的,除非 EXE 和 DLL 都是在启用运行时包的情况下编译的,以便它们共享一个公共实例相同的 RTL 和 VCL 框架(但随后您必须使用您的应用程序部署 RTL/VCL BPL 二进制文件)。

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

所以你的选择是:

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

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

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