MyMathFun.h

  1. #pragma once
  2.  
  3. // #ifdef DLLCLASS_API
  4. // #define DLLCLASS_API _declspec(dllimport)
  5. // #else
  6. // #define DLLCLASS_API _declspec(dllexport)
  7. // #endif
  8.  
  9. #define DLLCLASS_API _declspec(dllexport)
  10. class DLLCLASS_API MyMathFun
  11. {
  12. public:
  13. MyMathFun(void);
  14. ~MyMathFun(void);
  15. double Add(double a,double b);
  16. double Substract(double a,double b);
  17. double Multiply(double a,double b);
  18. double Divide(double a,double b);
  19. };

  

MyMathFun.cpp

  1. #include "MyMathFun.h"
  2.  
  3. #include <stdexcept>
  4. using namespace std;
  5. MyMathFun::MyMathFun(void)
  6. {
  7. }
  8. MyMathFun::~MyMathFun(void)
  9. {
  10. }
  11. double MyMathFun::Add(double a,double b)
  12. {
  13. return a+b;
  14. }
  15. double MyMathFun::Substract(double a,double b)
  16. {
  17. return a-b;
  18. }
  19. double MyMathFun::Multiply(double a,double b)
  20. {
  21. return a*b;
  22. }
  23. double MyMathFun::Divide(double a,double b)
  24. {
  25. if (b==0)
  26. {
  27. throw new invalid_argument("b cannot be zero!");
  28. }
  29. return a/b;
  30. }

  程序调用:

  1. #include <iostream>
  2. using namespace std;
  3. //当使用添加头文件目录,以便程序中包含的头文件存在(即可以找到):
  4. //1.项目,属性->C/C++->常规->附加包含目录:..\MathFunDll
  5. //2.#include "MyMathFun.h" 就可以省略下面的类的再次声明了
  6. #define DLLCLASS_API _declspec(dllimport)
  7. class DLLCLASS_API MyMathFun
  8. {
  9. public:
  10. MyMathFun(void);
  11. ~MyMathFun(void);
  12. double Add(double a,double b);
  13. double Substract(double a,double b);
  14. double Multiply(double a,double b);
  15. double Divide(double a,double b);
  16. };
  17. void main()
  18. {
  19. MyMathFun* mFun=new MyMathFun();
  20. cout<<mFun->Add(1,2)<<endl;//3
  21. cout<<mFun->Substract(3,4)<<endl;//-1
  22. cout<<mFun->Multiply(5,6)<<endl;//30
  23. cout<<mFun->Divide(7,8)<<endl;//0.875
  24. }

  

  1. 需要注意的地方:
  1. 1,不直接生成类的实例。对于类的大小,当我们定义一个类的实例,或使用new语句生成一个实例时,内存的大小是在编译时决定的。要使应用程序不依赖于类的大小,只有一个办法:应用程序不生成类的实例,使用DLL中的函数来生成。把导出类的构造函数定义为私有的(privated),在导出类中提供静态 (static)成员函数(如NewInstance())用来生成类的实例。因为NewInstance()函数在新的DLL中会被重新编译,所以总能返回大小正确的实例内存。 
    2,不直接访问成员变量。应用程序直接访问类的成员变量时会用到该变量的偏移地址。所以避免偏移地址依赖的办法就是不要直接访问成员变量。把所有的成员变量的访问控制都定义为保护型(protected)以上的级别,并为需要访问的成员变量定义GetSet方法。GetSet方法在编译新DLL时会被重新编译,所以总能访问到正确的变量位置。 
    3,忘了虚函数吧,就算有也不要让应用程序直接访问它。因为类的构造函数已经是私有(privated)的了,所以应用程序也不会去继承这个类,也不会实现自己的多态。如果导出类的父类中有虚函数,或设计需要(如类工场之类的框架),一定要把这些函数声明为保护的(protected)以上的级别,并为应用程序重新设计调用该虑函数的成员函数。这一点也类似于对成员变量的处理。
  1. 所以在创建类指针或者对象时,最好是在类里面的实例函数来创建,下面上一个创建类指针的例子:我这里以类CSetting为例子
  1. 首先在类的头文件public下创建函数static CSetting* GetInstace();
  1. 接着在类的头文件下面新建private,在里面创建类指针,定义:static CSetting* m_pInstance;
  1. 接着在cpp文件中初始化一下指针,一般赋空 CSetting* CSetting::m_pInstance = NULL;(不在构造函数中初始化,放在包含文件下面即可)
  1. cpp文件的析构函数中,添加指针释放:
  1. CSetting::~CSetting()
  2. {
  3. if(m_pInstance)
  4. {
  5. delete m_pInstance;
  6. m_pInstance = NULL;
  7. }
  8. }

  

  1. 接着最后一步,创建函数GetInstance(),代码如下:
  1. CSetting* CSetting::GetInstace()
  2. {
  3. if(NULL == m_pInstance)
  4. {
  5. m_pInstance = new CSetting;
  6. }
  7. return m_pInstance;
  8. }

  

  1. 在其他程序代用此类的时候可以使用CSetting::GetInstance()来调用类里面的方法和属性
  1. 完成!

DLL 导出类的更多相关文章

  1. DLL导出类避免地狱问题的完美解决方案

    DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...

  2. DLL的概念、dll导出类(转贴)

    1. DLL的概念DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用.静态链接库与动态链接库的区别:(1)静态链接库与动态链 ...

  3. C++ DLL导出类 知识大全

    在公司使用C++ 做开发,公司的大拿搭了一个C++的跨平台开发框架.在C++开发领域我还是个新手,有很多知识要学,比如Dll库的开发. 参考了很多这方面的资料,对DLL有一个基本全面的了解.有一个问题 ...

  4. [百度空间] [原]DLL导出实例化的模板类

    因为模板是在编译的时候根据模板参数实例化的,实例化之后就像一个普通的类(函数),这样才有对应的二进制代码;否则,没有模板参数,那么编译器就不知道怎么生成代码,所以生成的DLL就没有办法导出模板了.但是 ...

  5. dll的概念 dll导出变量 函数 类

    1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别:   (1)静态链接 ...

  6. C#调用C++导出类(转)

    由于使用别人的Dll,导出的是一个实体类,在C#里封送很难,百度下,有个朋友回复一篇英文的,虽然不一定使用,但可以作为一个知识点,现把原文贴下: c#调用C++写的dll导出类,包含继承,重载等详细介 ...

  7. DLL导出函数和类的定义区别 __declspec(dllexport)

    DLL导出函数和类的定义区别 __declspec(dllexport) 是有区别的, 请看 : //定义头文件的使用方,是导出还是导入 #if defined(_DLL_API) #ifndef D ...

  8. DLL入门浅析(4)——从DLL中导出类

    转载自:http://www.cppblog.com/suiaiguo/archive/2009/07/20/90663.html 前面介绍了怎么从DLL中导出函数和变量,实际上导出类的方法也是大同小 ...

  9. DLL导出函数和类 之 __declspec(dllexport)

    可利用__declspec(dllexport)导出函数或类. 若要指定C类型约定导出,则需在前面加extern “C”. 若要导出函数,__declspec(dllexport) 关键字必须出现在调 ...

随机推荐

  1. 关于Java在Linux or Android平台调用.so库

    Linux平台Java调用so库-JNI使用例子 android NDK开发及调用标准linux动态库.so文件 在Android项目中调用已有.so库 Android 调用.so文件 jni And ...

  2. BZOJ2720: [Violet 5]列队春游

    2720: [Violet 5]列队春游 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 173  Solved: 125[Submit][Status] ...

  3. 闭包用法,延迟tab

    var changeTab =( function () { var timeId = 0; return function (tabId) { if (timeId) { clearTimeout( ...

  4. 2.10. 代码片段:demo方法(Core Data 应用程序实践指南)

    该代码段我觉得没有太多东西 - (void)applicationDidBecomeActive:(UIApplication *)application { [self cdh]; [self de ...

  5. Windows API 函数浏览

    AbortDoc                                          终止一项打印作业                        是         是        ...

  6. html标签默认样式整理

    引:http://www.jb51.net/web/94964.html 文为大家整理了html标签默认样式属性及浏览器默认样式等等,喜欢css布局的朋友们可以学下,希望对大家有所帮助 html, a ...

  7. 车大棒浅谈for循环+canvas实现黑客帝国矩形阵

    背景: 一日在网上闲逛的之时,突然看到一个利用JQ插件实现canvas实现的电影黑客帝国的小Demo.觉得创意不错,就下载下来研究一下. 网上浏览jQuery的写法 $(document).ready ...

  8. sql数据库链接

    针对数据库只能链接计算机名称不能进行点(.)或者local本地链接的问题.主要会出现在刚装完系统的用户. 解决方法: 首先从SQL Server配置管理器中找到SQL Server网络配置的协议:TC ...

  9. CodeForces 722A

    A. Broken Clock time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

  10. HDU2602(背包)

    Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...