VC++动态库导出函数和类
来源:互联网 发布:windows编译php扩展 编辑:程序博客网 时间:2024/04/28 14:58
导出动态库中的函数和类首先需要加载动态库,加载的方式有两种,分为:隐式加载和显示加载。(编译器:VC++ 6.0)
对隐式加载还是显示加载的选择不明白请百度。
(一)隐式加载动态库
新建动态库工程,添加头文件和源文件,用以下几种方式分别导出“加减乘除”4个函数和point类,由于实现函数需要,因此添加了两个头文件。
动态库工程头文件(dlltest.h)代码如下:
#include<windows.h>#include<stdio.h>//_declspec(dllexport)作为导出函数的前缀,但是导出的函数名会发生改变_declspec(dllexport) int add(int a, int b);//extern "C"作为导出函数的前缀,导出的函数名不会发生改变,可以解决C和C++函数//调用时名字改编的问题,但是extern "C"只能导出全局函数extern "C" _declspec(dllexport) int sub(int m, int n);//添加.def文件导出此函数,解决了标准调用(pascal)和c调用之间名字改编的问题。//当实际函数名和def文件设置要导出的函数名一致时,导出的函数按实际名称导出;_declspec(dllexport) int mul(int x, int y);//当二者不一致时,可以按照如下格式导出函数:entryname = internalname_declspec(dllexport) int fun(int i, int j);class _declspec(dllexport) point {public:point(int x, int y);void output();private:int m;int n;};
动态库工程源文件(dlltest.cpp)代码如下:
#include "dlltest.h"int add(int a, int b){return a+b;}int sub(int m, int n){return m-n;}int mul(int x, int y){return x*y;}int fun(int i, int j){return i/j;}point::point(int x, int y){m = x;n = y;}void point::output(){ HWND m_hwnd = GetForegroundWindow(); HDC m_hdc = GetDC(m_hwnd); char buf[20] = {0}; sprintf(buf,"x=%d, y=%d",m,n); TextOut(m_hdc, 0, 0, buf, strlen(buf)); ReleaseDC(m_hwnd, m_hdc);}动态库工程编译成功之后生成引入库文件(dlltest.lib)和动态库文件(dlltest.dll).
导出的函数和类在VC++ 6.0自带的Denpedency Walker中查看如下所示,可以看到有的函数名字已经改变了,而有的函数没有改变:
接下来创建一个对话框工程,在对话框只放置一个按钮,按钮里对动态库的导出函数进行测试,分别创建对话框工程的头文件和源文件。
对话框工程的头文件(dllimport.h)代码如下:
//extern作为前缀声明add是外部定义的,此处也可以用_declspec(dllimport)//做外部声明,效率更高。extern int add(int a, int b);//由于在动态库中定义时前面还添加了extern "C" ,因此这里也必须添加,否//则编译不成功!extern "C" _declspec(dllimport) int sub(int m, int n);<pre name="code" class="cpp">//_declspec(dllimport)为前缀声明point类为导入类;//extern "C"只能用来导出全局函数,不能导出类和成员函数。class _declspec(dllimport) point {public:point(int x, int y);void output();private:int m;int n;};
对话框工程源文件(dlltest_jiemianDlg.cpp)按钮响应函数添加代码如下:
void CDlltest_jiemianDlg::OnBtnTest() {// TODO: Add your control notification handler code herepoint pt(3,5);pt.output();int num;CString strNum;num = add(1,2);strNum.Format("%d",num);MessageBox(strNum);num = sub(5,3);strNum.Format("%d",num);MessageBox(strNum);}对话框生成可执行程序(dlltest_jiemian.exe)
当对话框程序静态调用动态库时,需要做到3个步骤即可实现调用:
1>先把动态库的引入库文件和动态库文件放到对话框工程目录或Debug目录;
2>在对话框工程的Project->Settings->Object/library modules:设置栏添加动态库的引入库文件;
3>确保对话框对动态库中的导出函数和类做了声明(即是否包含dllimport.h这类文件)。
经测试,可以调用动态库导出的函数和类,结果如下图:
(二)显示加载动态库
由于显示加载和隐式加载动态库差不太多,这里就简单讲了。
显示加载和隐式加载声明函数的方式有很大不同,需注意!
头文件添加如下代码,此处的ADDFUC是定义的函数指针,声明sub函数式外部定义:
//>>=======================显式调用动态库dlltest.dll======================>>//注意:显式调用动态库无法导入类和类成员函数!!typedef int (*SUBFUC)(int a, int b);//<<=======================显式调用动态库dlltest.dll======================<<
源文件的按钮响应函数添加如下代码:
void CDlltest_jiemianDlg::OnBtnTest() {// TODO: Add your control notification handler code hereHMODULE hmodule; int num;CString strNum;hmodule = LoadLibrary("dlltest.dll");if (NULL == hmodule){MessageBox("can not find the dll");return;} SUBFUC subfun = (SUBFUC)GetProcAddress(hmodule, "sub");if (!subfun){MessageBox("get fun address failure");return;} num = subfun(5, 3);strNum.Format("%d",num);MessageBox("5-3="+strNum);}
运行结果如下:
由于动态库导出的add函数名字改成成了“?add@@YAHHH@”,因此若要导出add函数,则GetProcAddress函数的第二个参数不能之家些“add”,
而应该写“?add@@YAHHH@”,表示导出动态库的add函数,修改如下:
SUBFUC subfun = (SUBFUC)GetProcAddress(hmodule, "?add@@YAHHH@Z");
动态加载动态库有几个关键函数要注意,具体用法自行百度:
1>HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);
2>BOOL WINAPI FreeLibrary( _In_ HMODULE hModule);
3>FARPROC GetProcAddress(HMODULE hModule,LPCSTR lpProcName);
当对话框程序静态调用动态库时,需要做到3个步骤即可实现调用:
1>先把动态库的引入库文件和动态库文件放到对话框工程目录或Debug目录;
2>确保对话框对动态库中的导出函数和类做了声明(即是否包含dllimport.h这类文件)。
尤其注意,不要在对话框工程的Project->Settings->Object/library modules:设置栏添加动态库的引入库文件!
- VC++动态库导出函数和类
- vc++工程中.def文件的作用和动态库导出函数的方法.
- 编译VC++类的动态链接库DLL 导出类及其中的函数
- VC中创建DLL,导出全局变量,函数和类
- VC中创建DLL,导出全局变量,函数和类
- VC中导出类生成动态链接库的方式
- C/C++ (函数、变量和类)动态库的创建、导出和使用
- 动态链接库DLL导出函数的声明和调用
- VC中生成动态链接库的三种方式(导出函数)
- 更方便地动态调用DLL导出函数(VC++)
- VC DLL导出函数
- VC++ DLL 导出函数
- VC导出函数冲突
- VC++ DLL 导出函数
- C++动态链接库导出函数或者类
- VC中创建DLL,导出全局变量,函数和类 (转)
- 动态链接库导出函数的若干问题
- Linux从动态库导出函数
- 创建单利以及初始化
- centos 一键LNMP手记
- Odoo中自动备份数据库
- 深夜敲模板_1——快速幂 && 矩阵的快速幂
- 行内元素与块级元素比较全面的区别和转换
- VC++动态库导出函数和类
- 【UNITY3D 游戏开发之三】NGUI && HUDText 的练习源码及资源
- 收款机哈利和费德勒萨哈夫撒
- 程序员学习 javaAPI常用类
- FZU - 2148 Moon Game(暴力)
- boost log 使用问题
- redis 学习笔记(1)-编译、启动、停止
- redis 学习笔记(2)-client端示例代码
- LeetCode(073) Set Matrix Zeroes (Java)