社区
进程/线程/DLL
帖子详情
VC如何动态调用DLL里的函数?
wenyongjie
2004-07-26 11:30:01
有例子最佳
...全文
1133
4
打赏
收藏
VC如何动态调用DLL里的函数?
有例子最佳
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
kpld8888
2004-07-27
打赏
举报
回复
我有,qq:101059899,email:kpld@163.com
qqhuangshen
2004-07-27
打赏
举报
回复
综合以上例子,有两种调用动态连接库中的函数的方法
1.通过引入库:
利用Visual C++提供的IMPLIB工具为动态连接库生成引入库,为引入库设计一个头文件:
#ifndef _MYMATH_H
#define _MYMATH_H
extern “C”
{
int Summary(int n);
int Factorial(int n);
}
#endif
将该头文件包含在使用动态连接库的源文件中,连接应用程序时会连接上该引入库。这样,应用程序就可以象使用静态连接库一样自由的使用动态连接库中的函数了。注意要把动态连接库拷贝到应用程序可执行文件所在的目录(\TEST\DEBUG)下。
这是一种常用的方法。实际上,应用程序就是通过这种方式访问Windows的API函数的。Windows为其内核动态连接库生成引入库并提供了头文件。应用程序在编译时将引入库的信息带入可执行文件中,在运行时通过引入库信息访问API函数。
2. 直接指定库和函数地址
这种方式适合于一些提供文件格式转换等服务的动态连接库。比如,一个程序带有多个动态连接库,分别用于访问JPG、BMP、GIF等多种图像文件格式,这些动态连接库提供了相同的库函数接口。此时,无法使用引入库方式指定库函数。可以采用下面的方法来解决这个问题。
HANDLE hLibrary;
FARPROC lpFunc;
int nFormat;
if(nFormat==JPEG)//如果是JPEG格式,装入JPEG动态连接库
{
hLibrary=LoadLibrary(“JPEG.DLL”);
}
else//是GIF格式
hLibrary= LoadLibrary(“GIF.DLL”);
if(hLibrary>=32)
{
lpFunc=GetProcAddress(hLibrary,”ReadImage”);
if(lpFunc!=(FARPROC)NULL)
(*lpFunc)((LPCTSTR)strFileName);
FreeLibrary(hLibrary);
}
LoadLibrary函数装入所需的动态连接库,并返回库的句柄。如果句柄小于32,则载入库失败,错误含义参见有关手册。GetProcAddress函数使用函数名字取得函数的地址。利用该函数地址,就可以访问动态连接库的函数了。
qqhuangshen
2004-07-27
打赏
举报
回复
现在,来使用刚才生成的动态连接库。。首先,把mymaths\debug目录下的mymaths.dll拷贝到test\debug目录下。test程序运行时,会在该目录下搜索动态连接库文件。然后修改testdlg.h,在其中加入一个函数LoadDLL()的声明,LoadDLL用于载入动态连接库。
class CTestDlg : public CDialog
{
// Construction
public:
CTestDlg(CWnd* pParent = NULL); // standard constructor
protected:
void LoadDLL();
//......
}
然后修改testdlg.cpp,修改后如清单9.5。
清单95. TestDlg.cpp文件
// TestDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Test.h"
#include "TestDlg.h"
//#include "mymath.h" //注释掉mymath.h头文件
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//The instance of the Mymaths.DLL library
HINSTANCE ghMathsDLL=NULL;
//declare the Summary() function from the Mymaths.DLL libray.
typedef int (*SUMMARY)(int);
SUMMARY Summary;
//declare the Factorial() function from
//the Mymaths.DLL library.
typedef int (*FACTORIAL)(int);
FACTORIAL Factorial;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
//...
};
//CAboutDlg的一些成员函数定义
//CTestDlg的一些成员函数定义
void CTestDlg::OnSum()
{
// TODO: Add your control notification handler code here
LoadDLL();
int nSum=Summary(10);
CString sResult;
sResult.Format("Sum(10)=%d",nSum);
AfxMessageBox(sResult);
}
void CTestDlg::OnFactorial()
{
// TODO: Add your control notification handler code here
LoadDLL();
int nFact=Factorial(10);
CString sResult;
sResult.Format("10!=%d",nFact);
AfxMessageBox(sResult);
}
void CTestDlg::LoadDLL()
{
//如果DLL已经载入,则返回
if(ghMathsDLL!=NULL)
{
return;
}
//载入Mymaths.DLL文件.
ghMathsDLL=LoadLibrary("mymaths.DLL");
//如果载入DLL失败,提示用户
if(ghMathsDLL==NULL)
{
AfxMessageBox("Cannot load DLL file!");
}
//获得DLL中Summary函数的地址
Summary=(SUMMARY)GetProcAddress(ghMathsDLL,"Summary");
//获得DLL中Factorial函数的地址
Factorial=(FACTORIAL)GetProcAddress(ghMathsDLL,"Factorial");
}
在testdlg.cpp文件开头,加入:
//The instance of the Mymaths.DLL library
HINSTANCE ghMathsDLL=NULL;
//declare the Summary() function from the Mymaths.DLL libray.
typedef int (*SUMMARY)(int);
SUMMARY Summary;
//declare the Factorial() function from
//the Mymaths.DLL library.
typedef int (*FACTORIAL)(int);
FACTORIAL Factorial;
qqhuangshen
2004-07-27
打赏
举报
回复
譬如这样创建了如下DLL文件。最简单的求和函数和阶乘函数
文件1:mymaths.cpp
////////////////////////////
//mymaths.cpp
//
//a maths API DLL.
//
///////////////////////////
#include<windows.h>
//Declare the DLL functions prototypes
int Summary(int);
int Factorial(int);
//////////////////////////
//DllEntryPoint():The entry point of the DLL
//
/////////////////////////
BOOL WINAPI DLLEntryPoint(HINSTANCE hDLL,DWORD dwReason,
LPVOID Reserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
{
//一些初始化代码
break;
}
case DLL_PROCESS_DETACH:
{
//一些用于清理的代码
break;
}
}
return TRUE;
}
int Summary(int n)
{
int sum=0;
int i;
for(i=1;i<=n;i++)
{
sum+=i;
}
return sum;
}
int Factorial(int n)
{
int Fact=1;
int i;
for(i=1;i<=n;i++)
{
Fact=Fact*i;
}
return Fact;
}
文件2:mymaths.def
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Mymaths.DEF
;
;The DEF file for the Mymaths.DLL DLL.
;
LIBRARY mymaths
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE
EXPORTS
;The names of the DLL functions
Summary
Factorial
在文件mymaths.cpp开头,声明了动态连接库所包含的两个函数:Summary和Factorial。接着是DllEntryPoint()函数的定义。DllEntryPoint()顾名思义是动态连接库的入口,应用程序通过该入口访问动态连接库提供的服务。DllEntryPoint()主体是一个switch/case语句:
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
{
//一些初始化代码
break;
}
case DLL_PROCESS_DETACH:
{
//一些用于清理的代码
break;
}
}
Qt6之
调用
Windows下
vc
生成的
动态
链接库
dll
文章详细介绍了Windows系统下的
动态
链接库
DLL
的原理,包括
动态
链接库的定义、分类、开发与
调用
方法,以及如何在Qt中通过QLibrary进行
DLL
的
调用
。重点讲述了使用declspec(
dll
export)导出
函数
,以及Qt的QLibrary类在隐式链接
DLL
时的作用。
VC
动态
调用
DLL
本文介绍了如何在
VC
++中生成和
动态
调用
DLL
。首先展示了生成
DLL
的代码,包含一个整数加一的ADD
函数
和一个发送消息的SendMess
函数
,注意SendMess
函数
需要确保缓冲区已分配内存。接着详细阐述了在
VC
++中通过LoadLibrary和GetProcAddress
函数
动态
调用
DLL
中的ADD
函数
的过程。最后提到了在Delphi中
调用
相同
DLL
的方法,同样使用LoadLibrary和GetProcAddress,但需要进行类型转换来
调用
DLL
函数
。
VC
6.0中,创建、
调用
dll
本文介绍了如何使用
VC
6.0创建
DLL
动态
链接库,并详细阐述了生成
DLL
的步骤,包括设置项目类型和编写导出
函数
。同时,讲解了如何在新的Win32 Console Application中
调用
DLL
,通过LoadLibrary和GetProcAddress
函数
实现
函数
接口的
调用
。此外,还提到了访问
DLL
中的全局变量的方法。
delphi
调用
vc
写的
dll
的方法
本文介绍了如何在Delphi中
调用
VC
编写的
DLL
文件,详细展示了
DLL
中的
函数
声明及Delphi中的实现。同时,文章还讨论了字符串、PChar和字符数组之间的转换方法,提供实例代码进行演示。
在
VC
中
调用
DLL
文件
这篇博客介绍了在
VC
环境中如何进行
DLL
的隐式和显式链接。隐式链接是在程序开始时加载
DLL
,通过在头文件中声明导出
函数
并链接对应的lib文件。显式链接则允许程序运行时
动态
加载和卸载
DLL
,通过LoadLibrary和GetProcAddress
函数
获取
函数
指针。在使用
DLL
时,注意文件路径和
函数
序号的正确性。
进程/线程/DLL
15,465
社区成员
49,169
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章