求救!关于在dll中使用非基本控件报错的奇怪问题,问题比较棘手,请各位多帮忙.

纪俊 2005-04-11 09:33:10
下面是dll主文件代码,功能是实现一个插件式的模块
typedef struct PlugInModule{
AnsiString ver ;
AnsiString author ;
AnsiString menuMain;
AnsiString menuChild;
AnsiString description;
} PlugInModule ;

extern "C" __declspec(dllexport) PlugInModule __stdcall getModuleInfo();
extern "C" __declspec(dllexport) bool __stdcall executeModule();

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) PlugInModule __stdcall getModuleInfo()
{

PlugInModule modelInfo;
modelInfo.ver="1.00";
modelInfo.author="jj";
modelInfo.menuMain="Admin";
modelInfo.menuChild="Admin Database";
modelInfo.description="Admin Database Module";

return modelInfo;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) bool __stdcall executeModule()
{
MessageBox(0,"^_^","Dll Respond here:",0);
Form1 = new TForm1(NULL);
Form1->ShowModal();//调用Form1
delete Form1;
return 1;
}

此dll被主执行文件动态调用(用LoadLibrary与GetProcAddress得到getModuleInfo()与executeModule()并执行)
在dll中有一Form1,当Form1中只使用按钮、ListBox等基本控件的时候没有问题,但是当在Form1中使用ADO、以及一些其他非基本控件的时候此dll就无法正常调用。

最奇怪的是:getModuleInfo()函数(通过第一次LoadLibrary与GetProcAddress得到)在任何情况下都是好用的,而executeModule()函数(通过第二次LoadLibrary与GetProcAddress得到,错误说****内存不可写)则在后一种情况下出错,但出错点不是Form1->ShowModal()处而是开始第一句都不能执行

请各位大侠救命...
...全文
168 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Behard 2005-04-12
  • 打赏
  • 举报
回复
不知道楼主什么意思
jishiping 2005-04-12
  • 打赏
  • 举报
回复
结构 PlugInModule 最好不要使用 AnsiString,否则 DLL 以及 EXE 的 bpr 中都要添加 MEMMGR.LIB 这个库文件。另外,getModuleInfo 这个函数,最好改为:
extern "C" __declspec(dllexport) void __stdcall getModuleInfo(PlugInModule*);

3996906 2005-04-12
  • 打赏
  • 举报
回复
你动态创建ado控件看看,用了删掉,雪客告诉他点代码~~~~~~~~~~~那个创建用(NULL)的那种
纪俊 2005-04-12
  • 打赏
  • 举报
回复
to Friecin(雪客)
在我使用ADO的时候把初始化代码也加上了但是出一样的错误.
纪俊 2005-04-12
  • 打赏
  • 举报
回复
是忘记了...多谢!
jishiping 2005-04-12
  • 打赏
  • 举报
回复
当你用BCB的向导创建一个DLL时,自动产生的DLL的主文件里,在 DllEntryPoint 函数之前,有一段注释,说的就是 AnsiString 和 MEMMGR.LIB,看来你从来没有看这段说明啊。
纪俊 2005-04-12
  • 打赏
  • 举报
回复
to:季大哥
终于用数组把问题解决了
用第一种方法确实行不通但为什么呢?想不通
“结构 PlugInModule 最好不要使用 AnsiString,否则 DLL 以及 EXE 的 bpr 中都要添加 MEMMGR.LIB 这个库文件。另外,getModuleInfo 这个函数,最好改为:
extern "C" __declspec(dllexport) void __stdcall getModuleInfo(PlugInModule*);”
这个是为什么呢?能再给解释下么?
constantine 2005-04-12
  • 打赏
  • 举报
回复
ado得问题应该是没有加入头文件吧,检查看看是不是,如果动态调用要记得自己加上
jishiping 2005-04-12
  • 打赏
  • 举报
回复
看样子,你后来定义的PlugInModule,所有变量的类型都是char*,这样可能不好。看你这儿的getModuleInfo,好像所有的PlugInModule的数值度相同,这样到没有什么,否则应该这样定义:
struct PlugInModule
{
char ver[9];
char author[9];
char menuMain[17];
char menuChild[17];
char description[33];
};
上面的所有数组的大小,根据你那儿的需要来修改,原则上最好比实际的稍微大一点,防止
以后扩充。这样的话,getModuleInfo 就要改为:
extern "C" __declspec(dllexport) void __stdcall getModuleInfo(PlugInModule* giveModel)
{
strcpy(giveModel->ver, "1.00");
strcpy(giveModel->author, "jj");
strcpy(giveModel->menuMain, "Admin");
strcpy(giveModel->menuChild, "Admin Database");
strcpy(giveModel->description, "Admin Database Module");
}
jishiping 2005-04-12
  • 打赏
  • 举报
回复
上面的用法错误,由于 PlugInModule modelInfo; 是局部变量,在函数getModuleInfo
的外部,变量modelInfo已经释放了,此时将得到的giveModel是非法的指针,会导致程
序运行出错的。正确的是:
extern "C" __declspec(dllexport) void __stdcall getModuleInfo(PlugInModule* giveModel)
{
giveModel->ver="1.00";
giveModel->author="jj";
giveModel->menuMain="Admin";
giveModel->menuChild="Admin Database";
giveModel->description="Admin Database Module";
}

在调用这个函数时,先定义一个PlugInModule变量:
PlugInModule giveModel;
getModuleInfo(&giveModel);
纪俊 2005-04-12
  • 打赏
  • 举报
回复
jishiping(JSP 季世平) 大哥真的是很强...晚辈佩服啊....
能给小弟讲下你所说的两个问题的原因么?
我使用了你的方法修改了代码之后问题就解决了,但为什么在不使用非基本控件的时候没有问题呢?(但是偶尔在退出程序后报告3次非法操作)

还有一个小问题就是AnsiString改为char *之后,用下面的方法传递结构体
extern "C" __declspec(dllexport) void __stdcall getModuleInfo(PlugInModule* giveModel)
{

PlugInModule modelInfo;
modelInfo.ver="1.00";
modelInfo.author="jj";
modelInfo.menuMain="Admin";
modelInfo.menuChild="Admin Database";
modelInfo.description="Admin Database Module";

giveModel=&modelInfo;
}
但是在主模块得到moduleInfo后为什么moduleInfo.ver等元素都变为乱码了呢?
使用的代码如下:
typedef __stdcall void (Module_getModuleInfo)(PlugInModule*);
Module_getModuleInfo * getModuleInfo=(Module_getModuleInfo*)GetProcAddress(hModule,"getModuleInfo");
if(getModuleInfo){
(*getModuleInfo)(&moduleInfo);
}
FreeLibrary(hModule);

顺便再问个小问题:我把BCB的代码Copy到其他编辑器的时候里边的中文也都成了乱码,有什么方法可以解决这个问题么?

多谢季大哥了!
Friecin 2005-04-11
  • 打赏
  • 举报
回复
你用到ADO了吗?

如果用到了Com组建(ADO就是Com组件),那么,你一定要在DLL导入的地方加入:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
switch(reason)
{
case DLL_PROCESS_ATTACH: //初始化 COM
CoInitialize(NULL);
break;
case DLL_PROCESS_DETACH: //释放 COM
Application = NULL;
CoUninitialize();
break;

case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}

return 1;
}
//---------------------------------------------------------------------------
纪俊 2005-04-11
  • 打赏
  • 举报
回复
我就是把随便一个ADO控件比如ADOConnect拖放在Form1上就不行了
其他一些自己安装的控件也是...
3996906 2005-04-11
  • 打赏
  • 举报
回复
你里面的ado是怎么用的?放在上面的?动态创建的?说多点点

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧