高手救救我,关于DLL调用的问题

g_feng 2005-03-08 03:05:01
最近得到一个动态库,它里面的函数原形,举例如下:
int WINAPI TestFunc(DWORD &dwVolume);

我用tdump看到函数如下
000010C8 15 000E ?TestFunc@@YAHAAK@Z
我用以下代码:
typedef int (__cdecl *pTestFunc)(DWORD &);
pTestFunc TestFunc;
HINSTANCE hDLL;
hDLL = LoadLibrary("Test.dll");
if (hDLL != NULL)
{
TestFunc= (pTestFunc)GetProcAddress(hDLL,"TestFunc");
}
结果TestFunc总是为空值,请问我应该如何调用?
...全文
176 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
g_feng 2005-03-17
谢谢大家,其实前几天已经研究知道问题了。确实应该要用"?TestFunc@@YAHAAK@Z"作为函数名,才能取得到指针。动态库不是我写的,所以改原库文件是不行的,只能这样调用啦
回复
mythay 2005-03-14
我觉得有点奇怪,WINAPI指的是__stdcall,但是生成的DLL怎么又不是了呢。
要么你先按序号载入函数看成不成
回复
sx_enter 2005-03-14
你在GetProcAddress时候,要用"?TestFunc@@YAHAAK@Z"作为函数名,才能取得到指针。
回复
BigFanOfCpp 2005-03-12
TestFunc = (pTestFunc)GetProcAddress(hDLL,"TestFunc");

你的函数原形写的不正确,应该是:

TestFunc = (pTestFunc)GetProcAddress(hDLL,"WINAPITestFunc");
回复
hyamw 2005-03-12
hDLL = LoadLibrary("Test.dll");//这一行调用确定成功了?也就是hDLL != NULL?
回复
whs1980 2005-03-12
在原库中,它用C调用约定进行调用.typedef int (__cdecl *pTestFunc)(DWORD &);个人觉得是不是应该改为:typedef int (*pTestFunc)(DWORD &);
你在调用的时候,直接用WINAPITestFunc这个名字而不是TestFunc,系统会用C调用约定找到WINAPITestFunc函数
回复
yinzhaohui 2005-03-12
000010C8 15 000E ?TestFunc@@YAHAAK@Z
你在写动态链接时没有指定引出名规则,使用extern "C"约束为C的这样引出名为TestFunc,但是不充许在这个DLL中有同样的名字出现,参数样同,后而@@YAHAAK@Z各种编译器可能不一样,一般表示函数的参数和后回值如果是类中的方法表示列复杂一些,
你可以使用
TestFunc = (pTestFunc)GetProcAddress(hDLL,"TestFunc@@YAHAAK@Z");一找到它
也可以在DLL中使用C的定义或在def文件中定义它
回复
sinall 2005-03-09
试试显式调用
回复
xuzheng318 2005-03-08
加最个extern "C"与__stdcall
对调用处的重一定义一下,pTestFunc
回复
g_feng 2005-03-08
用它的静态库是可以的,但现在我要动态调用
回复
g_feng 2005-03-08
stdcall我试了也是不行,而且查了相关资料:

__stdcall调用约定:
1、以“?”标识函数名的开始,后跟函数名;
2、函数名后面以“@@YG”标识参数表的开始,后跟参数表;
3、参数表以代号表示:
X--void ,
D--char,
E--unsigned char,
F--short,
H--int,
I--unsigned int,
J--long,
K--unsigned long,
M--float,
N--double,
_N--bool,
....
PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复;
4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;
5、参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。

其格式为“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如
int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”
void Test2() -----“?Test2@@YGXXZ”

__cdecl调用约定:
规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。

__fastcall调用约定:
规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。

回复
oyljerry 2005-03-08
函数调用约定
typedef int (__stdcall *pTestFunc)(DWORD &);
回复
发帖
进程/线程/DLL
创建于2007-09-28

1.5w+

社区成员

VC/MFC 进程/线程/DLL
申请成为版主
帖子事件
创建了帖子
2005-03-08 03:05
社区公告
暂无公告