怎样调用DLL里面的函数?

senkiner 2004-04-27 12:28:44
我在Visual C++ 2003中,建立了一个Win32 DLL项目名叫DllTest2,在“应用程序设置”中选定了“导出符号”,然后在VC自动生成的代码中,有DllTest2.h:

// 下列 ifdef 块是创建使从 DLL 导出更简单的
//宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLLTEST2_EXPORTS
// 符号编译的。在使用此 DLL 的
//任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// DLLTEST2_API 函数视为是从此 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef DLLTEST2_EXPORTS
#define DLLTEST2_API __declspec(dllexport)
#else
#define DLLTEST2_API __declspec(dllimport)
#endif

// 此类是从 DllTest2.dll 导出的
class DLLTEST2_API CDllTest2 {
public:
CDllTest2(void);
// TODO: 在此添加您的方法。
};

extern DLLTEST2_API int nDllTest2;

DLLTEST2_API int fnDllTest2(void);

有DllTest2.cpp:
// DllTest2.cpp : 定义 DLL 应用程序的入口点。
//

#include "stdafx.h"
#include "DllTest2.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// 这是导出变量的一个示例
DLLTEST2_API int nDllTest2=0;

// 这是导出函数的一个示例。
DLLTEST2_API int fnDllTest2(void)
{
return 42;
}

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 DllTest2.h
CDllTest2::CDllTest2()
{
return;
}
就这样编译后得到一些文件,然后建立一个Win32应用程序,想在代码中调用fnDllTest2,该怎样调用呢?
在网上找,找到两个代码片段:
第一个:
HMODULE hModule;
FARPROC lpFunc;
hModule=LoadLibrary("DllTest2.DLL");//调试时hModule为0x10000000
if(hModule)
lpFunc=GetProcAddress(hModule,"fnDllTest2");
if(lpFunc != (FARPROC)NULL))//运行时lpFunc始终为0
a = (*lpFunc)();
FreeLibrary(hModule);

第二个:
HMODULE hModule;
typedef int(CALLBACK* fnGetNumber)(void);
fnGetNumber GetNumber;
hModule = LoadLibrary("DllTest2.dll");//调试时hModule为0x10000000
GetNumber =(fnGetNumber)GetProcAddress(hModule,"fnDllTest2");
if(GetNumber)//运行时GetNumber始终为0
a = GetNumber();
FreeLibrary(hModule);
因为lpFunc,GetNumber为0(hModule都不为0,为什么他为0呢),所以无法调用函数fnDllTest2。
这两个代码段有没有错呢,还是它们不适合用来调用VC++2003自动生成的Dll。
怎样在Win32程序中调用DLL中的函数呢,就调用那个上面的fnDllTest2,如果包含DllTest2.h,附加DllTest2.lib就可以调用,不过这样一来,就不用LoadLibrary,GetProcAddress都解决了,可不可以不包含DllTest2.h,不附加DllTest2.lib,调用fnDllTest2呢
...全文
442 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
senkiner 2004-05-04
  • 打赏
  • 举报
回复
添加了 extern "C"
去掉了一个类 和 一个变量

senkiner 2004-05-04
  • 打赏
  • 举报
回复
//问题马马虎虎算是解决了。
//最后的代码是:

//DllTest2.h
#ifdef DLLTEST2_EXPORTS
#define DLLTEST2_API extern "C" __declspec(dllexport)
#else
#define DLLTEST2_API extern "C" __declspec(dllimport)
#endif

DLLTEST2_API int fnDllTest2(void);

//
// GetFontName.cpp : 定义 DLL 应用程序的入口点。
//

#include "stdafx.h"
#include "DllTest2.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// 这是导出函数的一个示例。
DLLTEST2_API int fnDllTest2(void)
{
return 42;
}
FengYuanMSFT 2004-04-28
  • 打赏
  • 举报
回复
Add extern "C" to header file too:

// In header

extern "C"
{
DLLTEST2_API int fnDllTest2(void);
}
wowuyinglingluan 2004-04-28
  • 打赏
  • 举报
回复
fnDllTest2@@YAHXZ 都被编译器篡改成这副德行了,还嘴硬没被篡改
或者你根本不知道C++编译器名字篡改这回事?
senkiner 2004-04-28
  • 打赏
  • 举报
回复
可能是因为已经有 extern DLLTEST2_API int nDllTest2; 了,所以无法 extern "C" 吧,总是会出现 error C2732: 链接规范与“fnDllTest2”的早期规范冲突 的错误

呵呵,没有因为一个不小心使导出函数被改名哈,用depends检查,得到:
PI: C++
Ordinal: N/A
Hint: 2 (0x0002)
Function:?fnDllTest2@@YAHXZ
Entry Point: Not Bound
看其他的DLL,发觉他们的PI是C,这是不是 FengYuanMSFT(袁峰) 说的 extern “C”形成的?呵呵,理解了 FengYuanMSFT(袁峰)的“C++ compiler adds extra characters to the function name, so it's not fnDllTest2 anymore”了哈……
先去吃饭,待会儿再来,Bye
weakwater 2004-04-28
  • 打赏
  • 举报
回复
包含它的头文件
连接lib文件
直接用导出的类声明对象就OK了
laker_tmj 2004-04-28
  • 打赏
  • 举报
回复
up learn
wowuyinglingluan 2004-04-28
  • 打赏
  • 举报
回复
首先,全局函数才能被导出,建议你不要使用这种方法:
更好的方法是建立一个DEF文件,具体的方法,你可以在MSDN中找到,

DEF文件允许你很好地获取到所有的对DLL导出函数的控制,而两位楼上的给出的方法仅能提供有限的控制。
我担心你一个不小心,不好意思,没有看见所有代码,你的导出函数已经被改名了,
具体可以通过depends工具来检查,向上面的情况,多半是被改名造成的。
两位楼上的提出的方法也是为了防止名字篡改
senkiner 2004-04-27
  • 打赏
  • 举报
回复
照楼上所说用上 extern "C" ,在生成DLL时会出现如下错误:
f:\My Documents\Visual Studio Projects\C++ Projects\7.1\DllTest2\DllTest2.cpp(29): error C2732: 链接规范与“fnDllTest2”的早期规范冲突
在 DllTest2.h 声明了:

#define DLLTEST2_API __declspec(dllexport)

extern DLLTEST2_API int nDllTest2;

DLLTEST2_API int fnDllTest2(void);

的,为什么会就没有了呢。
包含 DllTest2.h,附加DllTest2.lib后,可以直接调用fnDllTest2,但我不想给其他要用DllTest2.Dll的人提供DllTest2.h啊

另外,楼上的话我是半懂不懂哈,因为我的英文很poor!:)
FengYuanMSFT 2004-04-27
  • 打赏
  • 举报
回复
C++ compiler adds extra characters to the function name, so it's not fnDllTest2 anymore.

Use the following syntax or .def file to change name.

extern "C"
{
DLLTEST2_API int fnDllTest2(void)
{
return 42;
}
}

Or you can just add your DLL projects as dependeny project or your EXE, no need to add .lib.

Use dumpbin /exports on your DLL to double check exported function name.

www.fengyuan.com

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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