我来我网
https://5come5.cn
 
您尚未 登录  注册 | 菠菜 | 软件站 | 音乐站 | 邮箱1 | 邮箱2 | 风格选择 | 更多 » 
 

本页主题: 如何调用dll中定义的一个全局变量? 显示签名 | 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

依然随意



性别: 帅哥 状态: 该用户目前不在线
等级: 前途无量
家族: ⊙JAY菊爱园⊙
发贴: 5922
威望: 0
浮云: 760
在线等级:
注册时间: 2006-09-25
最后登陆: 2022-10-30

5come5帮你背单词 [ campaign /kæm'pein/ n. 战役,运动 ]


如何调用dll中定义的一个全局变量?

偶在dll中写了一个栈类,然后在其中实例化,并把它当作dll的输出变量,
请问在加载此dll后,怎样用这个变量?
顶端 Posted: 2007-06-13 10:59 | [楼 主]
coolboy





性别: 保密 状态: 该用户目前不在线
等级: 品行端正
发贴: 252
威望: 0
浮云: 1107
在线等级:
注册时间: 2005-10-02
最后登陆: 2016-04-25

5come5帮你背单词 [ excited /ik'saitid/ a. 激动的 ]


你是如何加载的DLL的?
隐式加载定义外部变量即可。
显式加载则调用LoadLibrary() & GetProcAddress()获得该变量指针。注意你的符号名。
ps:建议楼主不要在dll中输出变量,而应该仅输出函数。
顶端 Posted: 2007-06-13 13:37 | [1 楼]
coolboy





性别: 保密 状态: 该用户目前不在线
等级: 品行端正
发贴: 252
威望: 0
浮云: 1107
在线等级:
注册时间: 2005-10-02
最后登陆: 2016-04-25

5come5帮你背单词 [ sacrifice /'sækrifais/ n. 牺牲(品),祭祀;vt. 牺牲,献出,祭祀;vi. 祭祀 ]


Quote:
引用第7楼vista于2007-06-15 09:13发表的:

是显式加的,如果想在dll中定义常用类.怎么在可执行模块中实例化这个类呀?

你的类到底是在dll中实例化的,还是在客户程序中实例化的?

显示加载只能加载函数和变量。你可以在dll中实例化一个对象,作为全局变量,然后通过GetProcAddress()的到变量的指针。显示加载不必包含库文件。

要在客户程序中实例化,则必须隐式加载。你需要在客户程序中将完整的类的声明放进来。并加上__declspec(dllimport)声明,以表明你的类是定义在外部。然后包含dll的库文件就可以了。
顶端 Posted: 2007-06-15 11:39 | [2 楼]
coolboy





性别: 保密 状态: 该用户目前不在线
等级: 品行端正
发贴: 252
威望: 0
浮云: 1107
在线等级:
注册时间: 2005-10-02
最后登陆: 2016-04-25

5come5帮你背单词 [ couch /kaut/ n. 睡椅,长沙发椅;vt. 表达,隐含 ]


Quote:
引用第9楼依然随意于2007-06-15 12:03发表的:

是想在可执行模块中实例化dll模块中的类,
还有,如果是dll模块中已经实例化的类,怎样在可执行模块中访问喃?那个GetProcAddress()还可以获取变量呀?

你在dll中创建一个类指针,指向你实例化的那个对象,输出这个指针,就可以用GetProcAddress得这个到指针。
GetProcAddress()其实是通过符号名来获取地址的,用dumpbin查看dll的输出表,你就能看到你所属出的符号名了。
输出时建议遵循C调用约定,加上extern "C。
顶端 Posted: 2007-06-15 13:10 | [3 楼]
coolboy





性别: 保密 状态: 该用户目前不在线
等级: 品行端正
发贴: 252
威望: 0
浮云: 1107
在线等级:
注册时间: 2005-10-02
最后登陆: 2016-04-25

5come5帮你背单词 [ cash /kæ/ n. 现金,现钱;vt. 兑换成现金 ]


Quote:
引用第12楼依然随意于2007-06-15 20:41发表的:

GetProcAdress()要两个参数,函数指针类型的一个实例,
如:typedef void (* pFunc)(int ,int);
  pFunc mfunc;
然后将mfunc传给它,但如果要将变量指针取出,调用主程序中怎么定义这个参数呀,
.......

首先你要知道什么叫输出符号名,它就是GetProcAdress()的第二个参数,你可以用dumpbin -exports yourfile 查看你的dll的输出符号名。
比如我随便写的一个dll查看结果如下:

      1   0    00011410    ??0Cdll@@QAE@XZ
      2   1    00011375    ??0Point@@QAE@XZ
      3   2    000114E2    ??4Cdll@@QAEAAV0@ABV0@@Z
      4   3    000115CD    ??4Point@@QAEAAV0@ABV0@@Z
      5   4    000110AA    ?SetPoint@Point@@QAEXHH@Z
      6   5    00011389    ?fndll@@YAHXZ
      7   6    00037C40    ?ndll@@3HA
      8   7    00037C44    hello

其中最边上那列中那些酷似乱码一般的字符就是符号名,代表你所输出的变量或函数,而这个表实际是dll的输出表。GetProcAddree是怎么找到你输出的函数和变量的呢?很简单,他根据你给的符号名来查表,得到第三列中的偏移地址,然后做一些处理后返回给你,你就得到了函数或者变量的指针。所以你可以用dumpbin得到GetProcAdress()的第二个参数。

其次,你会注意到上面的表里最后一行似函数名乎比较规则,没有乱码,因为这个输出变量是按C调用约定(定义时加上extren "C"),其他的则是按C++调用约定。因为C++中出现了重载函数,函数名是一样的,所以为了区别这些函数,不得不加一些信息区别,这些函数名就看起来就比较乱。C中不允许函数同名,所以不需要加以区分。因此,你可以把你的变量按C约定输出,或者直接查看输出表,得到符号名。要注意,这里讨论的是显示链接,隐式链接不需要知道符号名,包含lib文件即可。

第三,你需要把得到的地址强制转换为原来的类型,是函数你就转换为函数指针,是变量你就转换为变量指针,是类你就转换为对象指针。注意你必须先声明这些类型,比如输出对象时你要先在客户程序中包含类的完整定义,但你不必实现它。同时,类中原本私有和保护的变量你依然无法访问。

另外,输出变量不是个好主意,因为这些变量必须是全局的,一旦你的dll被加载,这些变量就被创建了,比较浪费资源。我刚才试了一下,可以输出一个对象,但只能查看对象的属性,无法调用对象的方法,所以显示加载+输出全局对象是非常不好的一种做法。
顶端 Posted: 2007-06-15 22:39 | [4 楼]
coolboy





性别: 保密 状态: 该用户目前不在线
等级: 品行端正
发贴: 252
威望: 0
浮云: 1107
在线等级:
注册时间: 2005-10-02
最后登陆: 2016-04-25

5come5帮你背单词 [ teenager /'ti:neid3ə/ n. (BΛ~Bæ岁的)青少年 ]


Quote:
我的前提是#include中不包含example类的头文件,应为如果包含,我就不用费这么大劲了,就不用dll了.

That's impossible。我已经明确回答你了,你的程序必须有类的定义。你想想啊,你都不告诉计算机你的类长什么样,计算机怎么去访问你的类?计算机怎么知道你的类里到底是3个变量还是4个变量?他怎么知道这块内存放的是什么?
顶端 Posted: 2007-06-16 01:09 | [5 楼]
我来我网·5come5 Forum » 程序员之家

Total 0.010302(s) query 6, Time now is:11-23 13:07, Gzip enabled
Powered by PHPWind v5.3, Localized by 5come5 Tech Team, 黔ICP备16009856号