社区
进程/线程/DLL
帖子详情
VC如何动态调用DLL里的函数?
wenyongjie
2004-07-26 11:30:01
有例子最佳
...全文
1100
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;
}
}
QT编写
DLL
调用
示例 方法 参数 返回值 事件回调
QT编写
DLL
给外部程序
调用
示例 方法 参数 返回值 事件回调 : 1:C#或者 NET 第一步:引入命名空间; using System Runtime InteropServices; 第二步:声明
函数
必须与实际
DLL
中
函数
名及参数一致; [
Dll
Import "qt
dll
dll
" ] public static extern int add int i ; 第三步:
调用
函数
执行; Console WriteLine add 10 ToString ; 2:QT 第一步:引入头文件; #include <QLibrary> 第二步:定义
函数
指针 以备
调用
; typedef int Add int ; 第三步:载入
DLL
调用
函数
执行; QLibrary lib "qt
dll
dll
" ; lib load ; Add add Add lib resolve "add" ; add 50 ; 3:C或C++ 第一步:引入头文件; #include <windows h> 第二步:定义
函数
指针; typedef int Add int ; 第三步:载入
DLL
调用
函数
执行; HINSTANCE h
Dll
LoadLibrary "qt
dll
dll
" ; 载入
DLL
获取句柄 if h
Dll
NULL { Add add Add GetProcAddress h
Dll
"add" ; 获取
函数
地址 printf "%d" add 110 ; FreeLibrary h
Dll
; 释放
DLL
}">QT编写
DLL
给外部程序
调用
示例 方法 参数 返回值 事件回调 : 1:C#或者 NET 第一步:引入命名空间; using System Runtime InteropServices; 第二步:声明
函数
必须与实际
DLL
中
函数
名及参数一致; [
Dll
Import "qt
dll
dll
" ] public static extern int add in [更多]
VC
中
调用
dll
函数
的两种方法
一、显式
调用
1、定义
函数
指针 typedef int (*
dll
_mul)(int a,int b); 2、加载
dll
,并获取其程序实例句柄 HINSTANCE h
dll
=loadlibrary("c:/cpp
Dll
.
dll
"); 3、从
dll
实例句柄中获取
函数
指针
dll
_mul mymul=(
dll
_mul)GetProcAddress(h
dll
,"mul"); 4、使用获取
《C语言/C++学习指南》--
动态
库和静态库视频教学
本视频课程介绍C语言中
动态
库和静态库的基本概念,制作和使用方法,手工加载
动态
库方法,如何导出
函数
和类,以及
VC
的静态编译等等
VC
调用
DLL
调用
DLL
有两种方法:静态
调用
和
动态
调用
. 显式(静态)
调用
: LIB +
DLL
+ .H,注意.H中
dll
export改为
dll
import 隐式(
动态
)
调用
:
DLL
+
函数
原型声明,先LoadLibrary,再GetProcAddress(即找到
DLL
中
函数
的地址),不用后FreeLibrary
更方便地
动态
调用
DLL
导出
函数
(
VC
++)
Submitted by 李马 您可以任意转载这篇文章,但请在转载时注明原始链接和作者,谢谢。 在一般情况下,
动态
调用
DLL
导出
函数
的方法是: 用typedef为目标
函数
定义
函数
指针类型。用GetProcAddress获取
函数
指针。用
函数
指针进行
调用
。 但是,如果要
调用
的
函数
太多的话,这个方法难免流于繁琐——有太多的typedef、太多的GetProcAddress和太多的
函数
指针
进程/线程/DLL
15,472
社区成员
49,183
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章