如何从一个DLL中导出一个类函数,但不用编译?

firsthym 2010-08-27 09:30:20
我的程序需要使用一个DLL中的函数,但这些函数被封装在一个类里面,这个DLL给我提供了头文件和lib文件,这样每当这个DLL更新的时候,我都需要重新编译我的程序。

我现在不想编译我的程序,而是想直接将新的DLL copy到我的程序路径下,就可以用。

我现在的思路是用一个纯虚基类作为接口,然后用一个工厂函数生成这个类实例,就像这样:

extern "C" ICTEST CreateCTEST(){return new CTEST;}
当然,类结构如下:

class CTEST : public ICTEST
{...};


我的方法需要修改DLL的源代码,各位有其他方法吗?DLL是由另外一个team实现的,我现在不想改他们的源代码。
...全文
189 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
ddc 2010-08-30
  • 打赏
  • 举报
回复
不带这么干的,随便改接口,内存地址都变了,你还想不编译?
要不外包一个接口dll,他变你跟着变,甚至这个dll可以源代码给他们出(相当于你写了他们代码的一部分),至于COM,表面上是随便改,但那里的查询接口相当于一个中间层,还是要花时间写的。
xiaohuh421 2010-08-30
  • 打赏
  • 举报
回复
dll在的东西都有有地址的,只要你能想办法定位到他的地址就行了.
liufang421 2010-08-30
  • 打赏
  • 举报
回复
你是想动态加载DLL导出的类?应该不行但是你可以直接导出函数干吗封装在一个类里面?要不这样

#include "windows.h"
#include "stdio.h"

class test
{
public:
int ptest()
{
printf("test.ptest();\n");
return 0;
}
};

test *p;

BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
{
p=new test();
return true;
}

if(ul_reason_for_call==DLL_PROCESS_DETACH)
{
delete p;
return true;
}

else
{
return true;
}
}

int __declspec(dllexport) test_ptest()
{
return p->ptest();
}
csucdl 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用楼主 firsthym 的回复:]
我的程序需要使用一个DLL中的函数,但这些函数被封装在一个类里面,这个DLL给我提供了头文件和lib文件,这样每当这个DLL更新的时候,我都需要重新编译我的程序。

我现在不想编译我的程序,而是想直接将新的DLL copy到我的程序路径下,就可以用。

我现在的思路是用一个纯虚基类作为接口,然后用一个工厂函数生成这个类实例,就像这样:

extern "C" ICTEST Create……
[/Quote]

应该不能实现你的需求, 建议使用COM, 通过运行时类型库来使用
ztenv 版主 2010-08-27
  • 打赏
  • 举报
回复
不修改dll源码?只修改你的程序?真的没有明白是什么意思;你的实现在dll中呢,只要dll的接口没有变,只修改dll没必要修改你的程序;
firsthym 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lianshaohua 的回复:]

那你的dll需要公布创建与删除类的实例函数,这样就可以通过抽象类来用了;
[/Quote]
这是当然的。但这需要修改DLL的源代码,我现在就是不想修改DLL,而只是修改我的程序就达到不编译的目的,不知道有其他思路没?
ztenv 版主 2010-08-27
  • 打赏
  • 举报
回复
那你的dll需要公布创建与删除类的实例函数,这样就可以通过抽象类来用了;
firsthym 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 lianshaohua 的回复:]

引用 7 楼 firsthym 的回复:
引用 5 楼 lianshaohua 的回复:

公布类的dll不能这么做的;当改了dll之后,lib库也就不一样的,同样在你调用的时候会找不到地址的;所以导出类的使用有很多问题,每次更改都必须重新编译;貌似没有办法;

用我的那个思路是可以的,因为我完全不需要lib了,只要接口函数的声明没有变化。

你没有明白lib是做什么的,更没有明白……
[/Quote]
因为我用的是虚函数表,这样我就完全不用关心函数地址的问题了。
ztenv 版主 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 firsthym 的回复:]
引用 5 楼 lianshaohua 的回复:

公布类的dll不能这么做的;当改了dll之后,lib库也就不一样的,同样在你调用的时候会找不到地址的;所以导出类的使用有很多问题,每次更改都必须重新编译;貌似没有办法;

用我的那个思路是可以的,因为我完全不需要lib了,只要接口函数的声明没有变化。
[/Quote]
你没有明白lib是做什么的,更没有明白调用类的时候是如何查询地址的,接口虽然没变,但是类的一些函数顺序及结构有变化呢?你怎么办?你以前的dll并不认识你新加的数据,并且有可能函数地址早已经改变了位置;你还能在原来的位置找到你的函数地址吗?找不到了;
向立天 2010-08-27
  • 打赏
  • 举报
回复
你可以考虑用com技术
taodm 2010-08-27
  • 打赏
  • 举报
回复
所以,使用纯C接口的标准dll.
珍惜生命,远离扩展dll
firsthym 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhoutanliang 的回复:]

dll修改不影响你已经编译好的程序啊

但如果接口也该了

那就没办法了

dll的设计初衷不就是这个吗

所以设计一个好的接口才是。。
[/Quote]
如果我用头文件和lib文件来编译我的程序,如果DLL有变动,比如增加了一些成员变量,导致类的内存结构发生变化,那么我的程序不重新编译的话,运行时会遇到问题,比如crash。
firsthym 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lianshaohua 的回复:]

公布类的dll不能这么做的;当改了dll之后,lib库也就不一样的,同样在你调用的时候会找不到地址的;所以导出类的使用有很多问题,每次更改都必须重新编译;貌似没有办法;
[/Quote]
用我的那个思路是可以的,因为我完全不需要lib了,只要接口函数的声明没有变化。
ztenv 版主 2010-08-27
  • 打赏
  • 举报
回复
如果是导出函数,就不存在我上面讲的问题了;
ztenv 版主 2010-08-27
  • 打赏
  • 举报
回复
公布类的dll不能这么做的;当改了dll之后,lib库也就不一样的,同样在你调用的时候会找不到地址的;所以导出类的使用有很多问题,每次更改都必须重新编译;貌似没有办法;
firsthym 2010-08-27
  • 打赏
  • 举报
回复
我想表达的是,我并不想去修改那个DLL的源代码,所有有其他思路没有?

我知道,如果是函数导出的话,完全可以用LoadLibrary()和GetProcAddress(),但是一个类封装了这些函数,这是我的难点。
lazy_2010 2010-08-27
  • 打赏
  • 举报
回复
这个另外一个 team 的决定既然选择了使用输出类的 MFC extension dll,就必须在库接口类修改的时候,重新 build 了。

还是尽量少使用这种 MFC extension dll 的处理方式吧。
AlanBruce 2010-08-27
  • 打赏
  • 举报
回复
dll修改不影响你已经编译好的程序啊

但如果接口也该了

那就没办法了

dll的设计初衷不就是这个吗

所以设计一个好的接口才是。。
healer_kx 2010-08-27
  • 打赏
  • 举报
回复
你的思路很好啊,但是这样也要改DLL的代码吧?

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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