以前看到大家经常提到关于dll里使用数据模块的问题,大家讨论得非常的热烈.我结合自己掌握的程度和参考了一些相关的资料,决定把它发在帖子里.愿对dll不太了解的朋友能开拓一些思路,同时希望高手们多多指教!!!!
我们在窗体中使用数据模块,一般所来大致需要两步:
1.在使用数据模块的任一窗体之前就确认数据模块将被创建(如果需要的话,我们可以通过修改 工程的源代码或自己创建表来更改创建顺序).如果窗体不是自动创建的,则只需要简单地需要时创建新的,并在需要时删除.
2.在将要使用的数据模块的窗体上要包含头文件.
如果用户正在使用数据模块,并且需要数据模块在dll被装载的一段时间里保持打开的状态.我们可以在DLLEntryPoint()中打开数据模块.
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include <Forms.hpp>
#include <TestDataModuleUnit.h>
#pragma argsused
String InternallyMaintainedResultString;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if (TestDataModule == NULL)
{
Application->Initialize();
Application->CreateForm(__classid(TTestDataModule), &TestDataModule);
}
return 1;
}
//导出函数
char *__declspec(dllexport)TestDLLInterfaceFunction(void)
{
TestDataModule->Query->First();
InternallyMaintainedResultString = TestDataModule->Query->FieldByName("SUMMARY")->AsString;
return InternallyMaintainedResultString.c_str();
}
//处理不规则的用数据模块继承的窗体
如果用户想使用一个派生数据模块,而该数据模块带用一个引用到数据模块祖先的基类窗体,当他在查找基本数据模块时,需要对在运行阶段的组件,查找系统找到派生类.基本类是Base1, Base2,派生类是
Descendant1和Descendant2.
//
TFindGlobalComponent OldFindGlobalComponent;
TComponet* __fastcall FindGlobalComponentExtended(const System::AnsiString Name)
{
if (Name == "Base1") return (TComponent*)(Base1*)Descendant1;
if (Name == "Base2") return (TComponent*)(Base2*)Descendant2;
return OldFindGlobalComponent(Name);
}
主函数:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
OldFindGlobalComponent = FindGlobalComponent;
FindGlobalComponent = FindGlobalComponentExtended;
}
}
此外, 每一个数据模块的构造程序(基类或派生)必须设置数据模块全局变量, 因为该全局变量的自动化初始化不能在其祖先类中发生.for example;
Base1 = this;
在Descendant1中:
Descendant1 = this;
转载于:https://www.cnblogs.com/yxhua240/archive/2010/04/06/1705511.html