模块封装(H,Lib,Dll)

分类:
  1. 普通C封装成DLL:win32 DLL
  2. MFC 规则DLL《静态版、动态版》:只能导出自己的C++类
  3. MFC 扩展DLL《动态版》: 能够导出MFC类,C++类
dumpbin  Depends


头文件:

  1. const char* g-szWorld;只声明不定义,避免多次包含后产生Bug;
  2. 函数声明为extern 为外部定义
  3. 纯C输出:extern "C" 就是不改编函数名; 不能修饰类成员函数,且调用方式不能改变(C的调用约定)(vc是stdcall pascal的调用约定)
  4. 尽量避免头文件包含头文件,cpp中包含,h中 class A 申明
  5. 跨平台写法:define 
  6. 可多次包含的声明(函数声明,类定义,数值常量)
#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内声明的接口函数。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值