2013-10-16 37 views
0

我有一些用C++ Builder 6創建的數據模塊。它們每個都使用另一個datamodule初始化與數據庫的連接。我試圖從這些數據模塊中創建一個DLL。DLL在創建ADO對象時給出異常程序終止

在創建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); 
} 
+1

你有沒有嘗試調試你的代碼,看看它爲什麼崩潰?此外,每次調用GetUserName()時都會創建新的DataModule對象,但您並未解放它們。而且你根本不應該調用CoInitialize()。您正在爲調用者設置COM公寓模型,這可能是完全錯誤的操作或使用錯誤的模型等。如果您確實需要控制DLL內的COM公寓模型,請將DataModules移動到其自己的工作人員線。 –

+0

如果我刪除了CoInitialize,我得到錯誤'CoInitialize has not been called'。我想在DllEntryPoint()中創建數據模塊,但那些也會給出錯誤。所以我把它們包裝在一個if結構中,只創建一次。 – Gudgip

+0

COM基於每個線程進行初始化。一旦線程的COM模型(公寓vs多線程)已經設置,它就不能在以後更改。如果您的DLL在調用方之前調用CoInitialize(),您的參數將優先,這可能不符合調用方的需求。如果您想在不影響調用者的情況下控制DM的COM設置,則必須將DM移動到他們自己的線程。此外,無論如何DllEntryPoint()並不適合初始化它們。 OS限制了允許DllEntryPoint()執行的操作。 –

回答

0

我引用雷米勒博:

COM基於每個線程進行初始化。一旦線程的COM模型 (公寓vs多線程)已被設置,它將不能在以後更改。 如果您的DLL在調用方之前調用CoInitialize(),您的參數將優先考慮,這可能不符合調用者的需求 。如果您想控制DM的COM設置而不影響調用者,則必須將DM移動到他們自己的線程。 此外,DllEntryPoint()不適合初始化 它們。 OS限制了允許DllEntryPoint()執行的操作。

這解決了這個問題。我必須在加載庫之前調用coInitialize()。