关于资源文件中DLL调用的问题-标题说不清,请进帖子

chifengwatch 2008-11-20 01:08:41
许久不用BCB,最近需要写段代码,要求只生成一个单一的EXE文件。
但是,这个EXE文件需要调用一个外部的DLL文件。
于是想到将此DLL文件作为资源文件包含在编译后的EXE文件中,在EXE文件运行时释放出DLL,用以调用。

DLL文件中封装了许多类,我在BCB窗口中声明这些类必须是全局类型,即窗口中各控件的事件均可以访问这些变量。

例如:DLL中封装了类CLASS_A,我在BCB中声明 CLASS_A MY_CLASS_A;此MY_CLASS_A我需要在窗口中的很多事件中调用,我只能将它声明为全局类型的变量。

代码编译没有问题。EXE路径下不存在资源中的DLL文件时运行,报找不到XXX.DLL(资源中的DLL文件),程序无法运行。
如果EXE路径下存在资源中的DLL文件(不需要释放资源文件),则程序运行正常。

替代方案倒是有,可以在此EXE外再加壳,不过这样似乎很难接受。

晕菜。难道需要动态创建全局变量?还是有其他的解决方法?请大家指教。谢谢XDJM了。


代码片段

#include <vcl.h>
#pragma hdrstop

#include "frmMain.h"
#include "IFSFNDBAS.h"
#pragma comment(lib,"ifsfndbas.lib")
#define DLLFILE "IFSFNDBAS.DLL"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

IFSFndUser MyFndUser; //实例化DLL中定义的类--出问题的地方

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{//释放DLL
if (!FileExists(ExtractFilePath(Application->ExeName)+DLLFILE))
{
TResourceStream &rs1 = *new TResourceStream( (int)HInstance, AnsiString("IFSDLL"),"DLLFILE" ) ;
try
{
rs1.SaveToFile( AnsiString(DLLFILE) ) ;
delete &rs1 ;
}
catch(...)
{
delete &rs1 ;
}
}
else
{
;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MyFndUser.XXX();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
MyFndUser.YYY();
}
...全文
223 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yumikoo 2008-11-20
  • 打赏
  • 举报
回复
先脱离你的程序,但是做个空EXE来调用这个DLL,静态和动态的都试试。有点古怪。不至于这样的。
僵哥 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 chifengwatch 的回复:]
引用 8 楼 ouygg 的回复:
IFSFndUser MyFndUser; //实例化DLL中定义的类--出问题的地方
这里不能是静态的,必需是动态的。



这正是我的问题,不知道怎么才能动态声明全局变量呢?
[/Quote]
用Function实现单例不就可以了
chifengwatch 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ouygg 的回复:]
IFSFndUser MyFndUser; //实例化DLL中定义的类--出问题的地方
这里不能是静态的,必需是动态的。
[/Quote]


这正是我的问题,不知道怎么才能动态声明全局变量呢?
chifengwatch 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 unsigned 的回复:]
另外一种就是将在链接(Linker)添加把这些DLL置为Delay Load,从而在工程的WinMain函数的最前部即Application->Initialize()之前进行检查,从而有机会释放DLL。
[/Quote]


晕,好久不来CSDN,不会回复了。

多谢回复,这样我试过,直接报windows错误报告对话框,不懂了。
chifengwatch 2008-11-20
  • 打赏
  • 举报
回复
多谢回复,这样我试过,直接报windows错误报告对话框,不懂了。
痞子酷 2008-11-20
  • 打赏
  • 举报
回复
IFSFndUser MyFndUser; //实例化DLL中定义的类--出问题的地方
这里不能是静态的,必需是动态的。
僵哥 2008-11-20
  • 打赏
  • 举报
回复
另外一种就是将在链接(Linker)添加把这些DLL置为Delay Load,从而在工程的WinMain函数的最前部即Application->Initialize()之前进行检查,从而有机会释放DLL。
僵哥 2008-11-20
  • 打赏
  • 举报
回复
DLL文件不要使用静态加载,换用动态加载.
jaffy 2008-11-20
  • 打赏
  • 举报
回复
代码编译没有问题。EXE路径下不存在资源中的DLL文件时运行,报找不到XXX.DLL(资源中的DLL文件),程序无法运行。
如果EXE路径下存在资源中的DLL文件(不需要释放资源文件),则程序运行正常。

---------------------------------------------------------
那就是释放DLL时的问题了
TripH0101 2008-11-20
  • 打赏
  • 举报
回复
MARK
yuanreid 2008-11-20
  • 打赏
  • 举报
回复
如果只声明,不实例化会不会报错?
如果只是实例化报错,能否放到加载dll后,再实例化呢?
jone7319 2008-11-20
  • 打赏
  • 举报
回复
UP
vc8fans 2008-11-20
  • 打赏
  • 举报
回复
想动态增加这种含有全局类的DLL,好像行不通
chifengwatch 2008-11-20
  • 打赏
  • 举报
回复
ok,结贴。感谢楼上的诸位。

太久不用BCB都忘光了,是自己钻牛角尖。

我把简单问题复杂化了。

delay load外部DLL,并在应用初始化前释放,将全局变量定义在头文件form的类中就解决了。

快5年不用BCB,不来CSDN的BCB板块了,大家还是那么热情,真好,谢谢各位。
jxw1987628 2008-11-20
  • 打赏
  • 举报
回复

// 如果类是从dll中导出的。

// 这些类需要在dll的头文件中有类的导出声明,和函数的导出声明一样的

// 可以在栈上创建实例的(一般你有公用的构造函数就行)

// 另外也可以如僵哥所说的创建1个单例。可以在和这个类的同1个dll中,用1个函数来创建这个类的实例。

// 然后导出这个函数(将实例以指针,或引用的方式传出),然后在外部调用这个导出函数来创建实例.

13,825

社区成员

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

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