关于动态调用dll的一些见识

在Windows编程中,除了在编译的时候链接lib文件跟dll挂上钩之外,还可以在运行的时候动态加载dll,这样更富于灵活性。这几天忙活这个问 题,搞得焦头烂额,因为GetProcAddress()始终得不到我说需要的函数名的地址。但是今天终于弄出结果来了,虽然有的地方还没有搞明白。
首先是__cdcel和__stdcall的问题。我就纠缠于这个问题上。最近几天都使用__stdcall,但是GetProcAddress始终不能成功。
我首先看到如下的程序:
        SHOWHTMLDIALOGFN *pfnShowHTMLDialog;

        pfnShowHTMLDialog = (SHOWHTMLDIALOGFN*) GetProcAddress(hinstMSHTML, "ShowHTMLDialog");

        if(pfnShowHTMLDialog)
        {
            IMoniker *moniker=NULL;

            //
            if( FAILED(CreateURLMoniker( NULL, (LPWSTR)url, &moniker ) ))
            {
                FreeLibrary(hinstMSHTML);
                return FALSE;
            }

            //调用ShowHTMLDialog函数显示URL上的HTML文件
            pfnShowHTMLDialog(NULL, moniker, NULL, NULL, NULL);
这里调用是没有问题的。而我看了下 mshtmlst.h中的定义,SHOWHTMLDIALOGFN就是使用__stdcall修饰的,以至于我一直没有明白为什么我的程序使用__stdcall修饰就没有用。
之后我固执于extern "C" 的问题,但是仍然使用 __stdcall修饰,结果无论是C文件还是Cpp文件的dll都无法正确获得地址。
后来我使用VC6的Depends工具察看dll结构终于看出了一点端倪。生成的dll中的函数名称都带有很多别的符号,我才大概明白了一点。
如下代码:
#define CDll_Public __declspec(dllexport)

#ifdef __cplusplus
extern "C" {
#define YESDEFINE -1
#endif

CDll_Public void __stdcall init(int );
CDll_Public void __stdcall add(int );    /*__stdcall not nessessary*/
CDll_Public int __stdcall ret();

#ifdef __cplusplus
}
#endif
的依赖察看结果是:
这时候我使用GetProcAddress(hin, "_init@4")就能够得到正确的结果。
但是这样做毕竟不是办法,最后我想到了使用__cdecl修饰看看效果,居然好了。然后就OK了。
#ifdef __cplusplus
extern "C" {
#endif

extern __declspec(dllexport) void __cdecl hello();
extern __declspec(dllexport) void hi();

#ifdef __cplusplus
}
#endif
这段代码生成的dll中的函数名称如下:

这样做的话就能够正确地动态加载dll了(C程序没问题,Cpp程序需要extern "C")。

PS。这里顺便把编译dll,以及link lib的命令写下来:
#生成dll
cl /LD cdll.c
#生成exe
cl cdlltest.c /link cdll.lib
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值