模块封装(H,Lib,Dll)
2012-08-13 10:38
211 查看
分类:
普通C封装成DLL:win32 DLL
MFC 规则DLL《静态版、动态版》:只能导出自己的C++类
MFC 扩展DLL《动态版》: 能够导出MFC类,C++类
dumpbinDepends
头文件:
const char* g-szWorld;只声明不定义,避免多次包含后产生Bug;
函数声明为extern 为外部定义
纯C输出:extern "C" 就是不改编函数名; 不能修饰类成员函数,且调用方式不能改变(C的调用约定)(vc是stdcall pascal的调用约定)
尽量避免头文件包含头文件,cpp中包含,h中 class A 申明
跨平台写法:define
可多次包含的声明(函数声明,类定义,数值常量)
DLL导出:
DLL导出(函数前缀指定extern "C" _declspec(export),def优先级最高)
DLL调用:
DLL调用(动态《 LoadLibrary》,静态《h,lib,dll》)
静态调用:
H:include头文件||extern int add()|| _declspec(dllimport) int add()
Lib: pragma comment || 编译器选项;
DLL:放在一起;
#include "..\\bin\\NetSdk.h"
#pragma comment (lib,"..\\bin\\NetSdk")
同级目录:
#include "bin\lib3ds.h"
#pragma comment (lib,"bin\\lib3ds")
上级目录:..
动态调用:只要dll文件即可;但你需知道函数类型
#include <stdio.h>
#include <windows.h>
typedef int (*lpAddFun)(int,int); //定义函数指针雏形
typedef long (__stdcall *lpcreathost)(char*,char *,int); //VC 默认是
int main()
{
HINSTANCE hDLL;
lpAddFun addFun=NULL;
hDLL=LoadLibrary("../Dlltest/Debug/Dlltest.dll");
if (hDLL!=NULL)
{
addFun=(lpAddFun)GetProcAddress(hDLL,"add");
if (addFun!=NULL)
{
printf("%d",addFun(2,3));
}
FreeLibrary(hDLL);
}
return 1;
}
DLL定义的全局变量可以被调用进程访问;DLL可以访问调用进程的全局数据。使用同一DLL的每一个
进程都有自己的DLL全局变量实例。如果多个线程并发访问同一变量,则需要使用同步机制;对一个
DLL的变量,如果希望每个使用DLL的线程都有自己的值,则应该使用线程局部存储(TLS,Thread
Local Strorage)。
一个MFC DLL的Example
1、在VS中新建MFC DLL工程。
2、建立对话框-声成相关类等等,和MFC编程无异。
3、接口文件的编写,这里是重点。
--------------------------------------------------------------
3.1、建立itface.h和itface.cpp两个文件并加入到工程中
3.2、itface.h的实现代码如下:
#ifdef DLL1_API
#else
#define DLL1_API extern "C" __declspec(dllimport)
#endif
DLL1_API showDlg();
3.3、itface.cpp实现代码如下
#define DLL1_API extern "C" __declspec(dllexport)
#include "stdafx.h"
#include "TestDlg.h"
#include "itface.h"//注意这里的预编译顺序
void showDlg()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg dlg;
dlg.DoModal();
}
3.4、编译完成后,切记用dependency工具查看dll函数是否导出。
-------------------------------------------------------------------------
4、建立测试程序,向测试程序提供三个文件,itface.h/dll/lib,然后在程序中实现如下代码
#pragma comment(lib,"mfcDll.lib")//声明lib文件
#include "itface.h"
之后,就可以在此源文件中任意调用itface.h内声明的接口函数。
普通C封装成DLL:win32 DLL
MFC 规则DLL《静态版、动态版》:只能导出自己的C++类
MFC 扩展DLL《动态版》: 能够导出MFC类,C++类
dumpbinDepends
头文件:
const char* g-szWorld;只声明不定义,避免多次包含后产生Bug;
函数声明为extern 为外部定义
纯C输出:extern "C" 就是不改编函数名; 不能修饰类成员函数,且调用方式不能改变(C的调用约定)(vc是stdcall pascal的调用约定)
尽量避免头文件包含头文件,cpp中包含,h中 class A 申明
跨平台写法:define
可多次包含的声明(函数声明,类定义,数值常量)
#ifndef INCLUDED_LIB3DS_H //预处理变量名 #define INCLUDED_LIB3DS_H //头文件中申明,不定义; //类, const 常初始化,inline函数 //其他均extern BaiDu"如何定义头文件" #ifndef LIB3DSAPI #ifdef _MSC_VER #ifdef LIB3DS_EXPORTS #define LIB3DSAPI __declspec(dllexport)//DLL制作中include,表明这些是要导出的,提供给其他模块用的! 制作DLL要提前包含 #else #define LIB3DSAPI __declspec(dllimport)//在自己程序中include,表明是由DLL提供 #endif #else #define LIB3DSAPI #endif #endif #ifdef __cplusplus extern "C" { #endif extern LIB3DSAPI void lib3ds_file_create_nodes_for_meshes(Lib3dsFile *file);//在其他C文件里有过定义 extern LIB3DSAPI void lib3ds_matrix_rotate_quat(float m[4][4], float q[4]); extern LIB3DSAPI void lib3ds_matrix_rotate(float m[4][4], float angle, float ax, float ay, float az); extern LIB3DSAPI void lib3ds_matrix_camera(float m[4][4], float pos[3], float tgt[3], float roll); #ifdef __cplusplus } #endif #endif //跨平台定义: #ifdef WIN32 #define THREADCREATE(func,argc,thread,id)\ thread=(HANDLE)-beginthreadex(...); #else #define THREADCREATE(func,argc,thread,id)\ pthread_create(); #endif
DLL导出:
DLL导出(函数前缀指定extern "C" _declspec(export),def优先级最高)
DLL调用:
DLL调用(动态《 LoadLibrary》,静态《h,lib,dll》)
静态调用:
H:include头文件||extern int add()|| _declspec(dllimport) int add()
Lib: pragma comment || 编译器选项;
DLL:放在一起;
#include "..\\bin\\NetSdk.h"
#pragma comment (lib,"..\\bin\\NetSdk")
同级目录:
#include "bin\lib3ds.h"
#pragma comment (lib,"bin\\lib3ds")
上级目录:..
动态调用:只要dll文件即可;但你需知道函数类型
#include <stdio.h>
#include <windows.h>
typedef int (*lpAddFun)(int,int); //定义函数指针雏形
typedef long (__stdcall *lpcreathost)(char*,char *,int); //VC 默认是
int main()
{
HINSTANCE hDLL;
lpAddFun addFun=NULL;
hDLL=LoadLibrary("../Dlltest/Debug/Dlltest.dll");
if (hDLL!=NULL)
{
addFun=(lpAddFun)GetProcAddress(hDLL,"add");
if (addFun!=NULL)
{
printf("%d",addFun(2,3));
}
FreeLibrary(hDLL);
}
return 1;
}
DLL定义的全局变量可以被调用进程访问;DLL可以访问调用进程的全局数据。使用同一DLL的每一个
进程都有自己的DLL全局变量实例。如果多个线程并发访问同一变量,则需要使用同步机制;对一个
DLL的变量,如果希望每个使用DLL的线程都有自己的值,则应该使用线程局部存储(TLS,Thread
Local Strorage)。
一个MFC DLL的Example
1、在VS中新建MFC DLL工程。
2、建立对话框-声成相关类等等,和MFC编程无异。
3、接口文件的编写,这里是重点。
--------------------------------------------------------------
3.1、建立itface.h和itface.cpp两个文件并加入到工程中
3.2、itface.h的实现代码如下:
#ifdef DLL1_API
#else
#define DLL1_API extern "C" __declspec(dllimport)
#endif
DLL1_API showDlg();
3.3、itface.cpp实现代码如下
#define DLL1_API extern "C" __declspec(dllexport)
#include "stdafx.h"
#include "TestDlg.h"
#include "itface.h"//注意这里的预编译顺序
void showDlg()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg dlg;
dlg.DoModal();
}
3.4、编译完成后,切记用dependency工具查看dll函数是否导出。
-------------------------------------------------------------------------
4、建立测试程序,向测试程序提供三个文件,itface.h/dll/lib,然后在程序中实现如下代码
#pragma comment(lib,"mfcDll.lib")//声明lib文件
#include "itface.h"
之后,就可以在此源文件中任意调用itface.h内声明的接口函数。
相关文章推荐
- 将自己写的经常复用的类封装成dll/lib的方法
- 微软libcaffe封装成dll和lib!!!
- MFC模块的动态链接库DLL以及静态链接库LIB编译后的调用
- dll、com 二进制模块封装内幕
- 将类封装成dll/lib的方法
- 将自己写的经常复用的类封装成dll/lib的方法
- dll、com 二进制模块封装内幕
- 用smtplib和email封装python发送邮件模块类分享
- 将自己写的经常复用的类封装成dll/lib的方法
- 将自己写的经常复用的类封装成dll/lib的方法
- 包含别人的dll,然后我们用类库再次封装成dll的时候的注意事项;源文件与模块生成时的文件不同;创建调试信息文件 ··PDB时发生意外的错误,进程无法访问文件,因为另一个程序正在使用此文件
- 模块dll和lib
- cmake编译opencv3.1+contribute模块,并提供编译后的dll、lib等文件下载
- 多个类封装dll即dll与lib
- MFC模块的动态链接库DLL以及静态链接库LIB编译后的调用
- Cannot load vendor library [libmysql.dll or libmysqld.dll]. 找不到指定的模块
- 关于在dll中封装系统模块的资料
- 将自己写的经常复用的类封装成dll/lib的方法
- 常用类的dll和lib封装方法
- Windows Dev Intro - Psapi.lib(PSAPI.DLL) : error LNK2026: 模块对于 SAFESEH 映像是不安全的