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被加载,这些变量就被创建了,比较浪费资源。我刚才试了一下,可以输出一个对象,但只能查看对象的属性,无法调用对象的方法,所以显示加载+输出全局对象是非常不好的一种做法。