0

C++ Builder 6 で作成されたいくつかのデータモジュールがあります。それらのそれぞれは、データベースとの接続を初期化する別のデータモジュールを使用します。これらのデータモジュールから DLL を作成しようとしています。

DataModule_Users の作成時にエラーがスローされ、「プログラムの異常終了」と表示されます。

どこが間違っていますか?

前もって感謝します

datamodule_dll.bpf

USEFORM("DataModule_Connection.cpp", DataModule_Connection); /* TDataModule: File Type */
USEFORM("DataModule_Users.cpp", DataModule_Users); /*TDataModule: File Type */
//------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file

DllEntryPoint

datamodule_DLL.cpp

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}
extern "C" __declspec(dllexport) const char * GetUserName(const char * ID);

const char * GetUserName(const char * ID) {
  CoInitialize(NULL); // datasets use COM
  // This is used by DataModule_Users (normally this is done with Application->CreateForm();
  DataModule_Connection = new DataModule_Connection( 0 /* Owner */ );
  DataModule_Users = new DataModule_Users( 0 /* Owner */ );
  return DataModule_Users->GetUserName(ID);
}
4

1 に答える 1

0

レミー・ルボーを引用します:

COM はスレッドごとに初期化されます。スレッドの COM モデル (アパートメントとマルチスレッド) が設定されると、後で変更することはできません。呼び出し元が呼び出す前に DLL が CoInitialize() を呼び出すと、パラメーターが優先され、呼び出し元のニーズを満たさない可能性があります。呼び出し元に影響を与えずに DM の COM 設定を制御する場合は、DM を独自のスレッドに移動する必要があります。その上、DllEntryPoint() はとにかくそれらを初期化する適切な場所ではありません。OS は、DllEntryPoint() が実行できることを制限します。

これで問題は解決しました。ライブラリをロードする前に、coInitialize() を呼び出す必要がありました。

于 2014-02-18T12:19:26.553 に答える