动态调用dll的问题

ClassDan 2010-03-06 08:10:25
Win32动态链接库工程Dll2:

/*************************main.h****************************/
#ifndef DLL_API
#define DLL_API _declspec(dllimport)
#endif

DLL_API int add(const int a,const int b);

/*************************main.cpp**************************/
#define DLL_API _declspec(dllexport)
#include "main.h"

int add(const int a,const int b)
{
return a+b;
}

MFC基于对话框工程TestDll2:

//对话框按钮“加法”(ID为IDC_BUTTON1)的消息响应
void CTestDll2Dlg::OnButton1()
{
HINSTANCE hDll=LoadLibrary("Dll2.dll");
if(!hDll)
{
MessageBox("加载动态链接库失败!");
return;
}

typedef int (*pAddProc)(const int a,const int b);
pAddProc add=(pAddProc)GetProcAddress(hDll,"add");
if(!add)
{
MessageBox("找不到指定函数!");
return;
}

CString str;
str.Format("3+5=%d",add(3,5));
MessageBox(str);

FreeLibrary(hDll);
}


将生成的动态链接库Dll2.dll复制到工程TestDll2所在的目录,运行TestDll2.exe,提示“找不到指定函数!”!这是为什么?没觉得代码有什么问题啊?
...全文
104 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
ClassDan 2010-03-16
  • 打赏
  • 举报
回复
OK,问题解决,结贴了~~
mcaok 2010-03-12
  • 打赏
  • 举报
回复
用def文件吧。
LIBRARY MyDLL
EXPORTS
//导出函数名
sunlin7 2010-03-06
  • 打赏
  • 举报
回复
C++为了支持函数重载,会根据函数的参数类型对函数的名字进行修饰,比如
int add(int, int)
的可能名字是?add?YHHY这样的,GetProcessAddress(hMod, ?add?YHHY")即可

但C语言的命名是简单的修饰,如
extern "C" int add(int, int)
的可能名字是_add@8这样的,GetProcessAddress(hMod, "_add@8")即可。

所以要精确控制导出名字,用.def文件
exports
add=add
这样可以导出这个函数,并且使用GetProcessAddress(hMod, "add")即可。
yxwsbobo 2010-03-06
  • 打赏
  • 举报
回复
c++ 有重载,他会改变名字的
ClassDan 2010-03-06
  • 打赏
  • 举报
回复
我怀疑是导出函数名不对,我将

pAddProc add=(pAddProc)GetProcAddress(hDll,"add");

改为:

pAddProc add=(pAddProc)GetProcAddress(hDll,"?add@@YAHHH@Z");

之后就可以正常运行了。
或者将动态链接库程序改为:

#define DLL_API extern "C" _declspec(dllexport)

也可以。

这么说就是导出函数名的问题了,但是两个工程都是用的VC开发工具,名称约定应该是一样的啊?为什么还要用extern "C"呢?
白云飘飘飘 2010-03-06
  • 打赏
  • 举报
回复
前面打错了,这样声明:int WINAPI add(const int a,const int b);
cdsnpeter 2010-03-06
  • 打赏
  • 举报
回复
depends查下,是不是没写模块定义文件。
白云飘飘飘 2010-03-06
  • 打赏
  • 举报
回复
不要用_declspec(dllimport)
这样声明:WINAPI int add(const int a,const int b);
用模块定义文件导出函数。
yxwsbobo 2010-03-06
  • 打赏
  • 举报
回复
重定义 那就把 #define DLL_API _declspec(dllexport) 放在最前面

没猜错的话 你的 main 是dll文件吧?


外部应用程序 如果想调用 dll中的函数 ,那么这个函数必须被声明为 _declspec(dllexport) 如果错的话,估计还需要 extern "C"
ClassDan 2010-03-06
  • 打赏
  • 举报
回复
引用 1 楼 yxwsbobo 的回复:
DLL_API int add(const int a,const int b);

应该放在  #define DLL_API _declspec(dllexport) 下面

不对吧?为什么要这样做呢?VC编译提示重定义。。。
yxwsbobo 2010-03-06
  • 打赏
  • 举报
回复
DLL_API int add(const int a,const int b);

应该放在 #define DLL_API _declspec(dllexport) 下面


15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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