2013-10-16 39 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()。