Совместимость приложений C++ XE 5 и C++ Builder 5 dll

У меня есть 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 без перекомпиляции dll в XE5?

1 ответ

Решение

Передавать / использовать объекты RTL/VCL через границу DLL небезопасно, как вы это делаете, если только EXE и DLL не скомпилированы с включенными пакетами времени выполнения, так что они совместно используют общий экземпляр тех же платформ RTL и VCL (но затем вы необходимо развернуть двоичные файлы RTL/VCL BPL с вашим приложением).

Ваша DLL не работает в XE5, потому что DLL ожидает версию BCB5 TDataSource компонент, а не версия XE5. Нет, они не совместимы, так как имеют разную структуру памяти и зависимости.

Таким образом, ваш выбор:

  1. перекомпилировать DLL в XE5, и жить с риском, что передача TDataSource за границей DLL вообще небезопасно, если только вы не включите пакеты времени выполнения.

  2. переписать библиотеку DLL, чтобы она стала пакетом времени выполнения (BPL). Потом прохождение TDataSource Между EXE и DLL безопасно. Однако пакеты времени выполнения зависят от версии, поэтому вам нужно будет скомпилировать отдельные BPL, если вам нужно продолжать использовать код в BCB5 и XE5.

  3. переписать DLL, чтобы не пропустить TDataSource через границу DLL для начала. Придумайте еще один безопасный для взаимодействия способ обмена данными между EXE и DLL.

Другие вопросы по тегам