DLL 导出类
MyMathFun.h
- #pragma once
- // #ifdef DLLCLASS_API
- // #define DLLCLASS_API _declspec(dllimport)
- // #else
- // #define DLLCLASS_API _declspec(dllexport)
- // #endif
- #define DLLCLASS_API _declspec(dllexport)
- class DLLCLASS_API MyMathFun
- {
- public:
- MyMathFun(void);
- ~MyMathFun(void);
- double Add(double a,double b);
- double Substract(double a,double b);
- double Multiply(double a,double b);
- double Divide(double a,double b);
- };
MyMathFun.cpp
- #include "MyMathFun.h"
- #include <stdexcept>
- using namespace std;
- MyMathFun::MyMathFun(void)
- {
- }
- MyMathFun::~MyMathFun(void)
- {
- }
- double MyMathFun::Add(double a,double b)
- {
- return a+b;
- }
- double MyMathFun::Substract(double a,double b)
- {
- return a-b;
- }
- double MyMathFun::Multiply(double a,double b)
- {
- return a*b;
- }
- double MyMathFun::Divide(double a,double b)
- {
- if (b==0)
- {
- throw new invalid_argument("b cannot be zero!");
- }
- return a/b;
- }
程序调用:
- #include <iostream>
- using namespace std;
- //当使用添加头文件目录,以便程序中包含的头文件存在(即可以找到):
- //1.项目,属性->C/C++->常规->附加包含目录:..\MathFunDll
- //2.#include "MyMathFun.h" 就可以省略下面的类的再次声明了
- #define DLLCLASS_API _declspec(dllimport)
- class DLLCLASS_API MyMathFun
- {
- public:
- MyMathFun(void);
- ~MyMathFun(void);
- double Add(double a,double b);
- double Substract(double a,double b);
- double Multiply(double a,double b);
- double Divide(double a,double b);
- };
- void main()
- {
- MyMathFun* mFun=new MyMathFun();
- cout<<mFun->Add(1,2)<<endl;//3
- cout<<mFun->Substract(3,4)<<endl;//-1
- cout<<mFun->Multiply(5,6)<<endl;//30
- cout<<mFun->Divide(7,8)<<endl;//0.875
- }
- 需要注意的地方:
- 1,不直接生成类的实例。对于类的大小,当我们定义一个类的实例,或使用new语句生成一个实例时,内存的大小是在编译时决定的。要使应用程序不依赖于类的大小,只有一个办法:应用程序不生成类的实例,使用DLL中的函数来生成。把导出类的构造函数定义为私有的(privated),在导出类中提供静态 (static)成员函数(如NewInstance())用来生成类的实例。因为NewInstance()函数在新的DLL中会被重新编译,所以总能返回大小正确的实例内存。
2,不直接访问成员变量。应用程序直接访问类的成员变量时会用到该变量的偏移地址。所以避免偏移地址依赖的办法就是不要直接访问成员变量。把所有的成员变量的访问控制都定义为保护型(protected)以上的级别,并为需要访问的成员变量定义Get或Set方法。Get或Set方法在编译新DLL时会被重新编译,所以总能访问到正确的变量位置。
3,忘了虚函数吧,就算有也不要让应用程序直接访问它。因为类的构造函数已经是私有(privated)的了,所以应用程序也不会去继承这个类,也不会实现自己的多态。如果导出类的父类中有虚函数,或设计需要(如类工场之类的框架),一定要把这些函数声明为保护的(protected)以上的级别,并为应用程序重新设计调用该虑函数的成员函数。这一点也类似于对成员变量的处理。
- 所以在创建类指针或者对象时,最好是在类里面的实例函数来创建,下面上一个创建类指针的例子:我这里以类CSetting为例子
- 首先在类的头文件public下创建函数static CSetting* GetInstace();
- 接着在类的头文件下面新建private,在里面创建类指针,定义:static CSetting* m_pInstance;
- 接着在cpp文件中初始化一下指针,一般赋空 CSetting* CSetting::m_pInstance = NULL;(不在构造函数中初始化,放在包含文件下面即可)
- 在cpp文件的析构函数中,添加指针释放:
- CSetting::~CSetting()
- {
- if(m_pInstance)
- {
- delete m_pInstance;
- m_pInstance = NULL;
- }
- }
- 接着最后一步,创建函数GetInstance(),代码如下:
- CSetting* CSetting::GetInstace()
- {
- if(NULL == m_pInstance)
- {
- m_pInstance = new CSetting;
- }
- return m_pInstance;
- }
- 在其他程序代用此类的时候可以使用CSetting::GetInstance()来调用类里面的方法和属性
- 完成!
DLL 导出类的更多相关文章
- DLL导出类避免地狱问题的完美解决方案
DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...
- DLL的概念、dll导出类(转贴)
1. DLL的概念DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用.静态链接库与动态链接库的区别:(1)静态链接库与动态链 ...
- C++ DLL导出类 知识大全
在公司使用C++ 做开发,公司的大拿搭了一个C++的跨平台开发框架.在C++开发领域我还是个新手,有很多知识要学,比如Dll库的开发. 参考了很多这方面的资料,对DLL有一个基本全面的了解.有一个问题 ...
- [百度空间] [原]DLL导出实例化的模板类
因为模板是在编译的时候根据模板参数实例化的,实例化之后就像一个普通的类(函数),这样才有对应的二进制代码;否则,没有模板参数,那么编译器就不知道怎么生成代码,所以生成的DLL就没有办法导出模板了.但是 ...
- dll的概念 dll导出变量 函数 类
1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别: (1)静态链接 ...
- C#调用C++导出类(转)
由于使用别人的Dll,导出的是一个实体类,在C#里封送很难,百度下,有个朋友回复一篇英文的,虽然不一定使用,但可以作为一个知识点,现把原文贴下: c#调用C++写的dll导出类,包含继承,重载等详细介 ...
- DLL导出函数和类的定义区别 __declspec(dllexport)
DLL导出函数和类的定义区别 __declspec(dllexport) 是有区别的, 请看 : //定义头文件的使用方,是导出还是导入 #if defined(_DLL_API) #ifndef D ...
- DLL入门浅析(4)——从DLL中导出类
转载自:http://www.cppblog.com/suiaiguo/archive/2009/07/20/90663.html 前面介绍了怎么从DLL中导出函数和变量,实际上导出类的方法也是大同小 ...
- DLL导出函数和类 之 __declspec(dllexport)
可利用__declspec(dllexport)导出函数或类. 若要指定C类型约定导出,则需在前面加extern “C”. 若要导出函数,__declspec(dllexport) 关键字必须出现在调 ...
随机推荐
- 关于Java在Linux or Android平台调用.so库
Linux平台Java调用so库-JNI使用例子 android NDK开发及调用标准linux动态库.so文件 在Android项目中调用已有.so库 Android 调用.so文件 jni And ...
- BZOJ2720: [Violet 5]列队春游
2720: [Violet 5]列队春游 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 173 Solved: 125[Submit][Status] ...
- 闭包用法,延迟tab
var changeTab =( function () { var timeId = 0; return function (tabId) { if (timeId) { clearTimeout( ...
- 2.10. 代码片段:demo方法(Core Data 应用程序实践指南)
该代码段我觉得没有太多东西 - (void)applicationDidBecomeActive:(UIApplication *)application { [self cdh]; [self de ...
- Windows API 函数浏览
AbortDoc 终止一项打印作业 是 是 ...
- html标签默认样式整理
引:http://www.jb51.net/web/94964.html 文为大家整理了html标签默认样式属性及浏览器默认样式等等,喜欢css布局的朋友们可以学下,希望对大家有所帮助 html, a ...
- 车大棒浅谈for循环+canvas实现黑客帝国矩形阵
背景: 一日在网上闲逛的之时,突然看到一个利用JQ插件实现canvas实现的电影黑客帝国的小Demo.觉得创意不错,就下载下来研究一下. 网上浏览jQuery的写法 $(document).ready ...
- sql数据库链接
针对数据库只能链接计算机名称不能进行点(.)或者local本地链接的问题.主要会出现在刚装完系统的用户. 解决方法: 首先从SQL Server配置管理器中找到SQL Server网络配置的协议:TC ...
- CodeForces 722A
A. Broken Clock time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
- HDU2602(背包)
Bone Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...