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()来调用类里面的方法和属性
完成!
时间: 2024-10-27 17:09:59

DLL 导出类的相关文章

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

DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类,以便在类的层次上实现复用.所幸的是,DLL确实也可以导出类. 然而事实却没这么简单,导出类的DLL在维护和修改时有很多地方必需很小心,增加成员变量.修改导出类的基类等操作都可能导致意想不到的后果,也许用户更新了最新版本的DLL库后,应用程序就再也不能工作了.这就是著名的DLL Hell(DLL地狱)

dll的概念、dll导出类

随笔- 64  文章- 0  评论- 37 dll的概念.dll导出类(转) 1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别: (1)静态链接库与动态链接库都是共享代码的方式.静态链接库把最后的指令都包含在最终生成的EXE文件中了:动态链接库不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件. (2)静态链接库中不能再

MFC DLL导出类

MFC DLL导出类 2011-06-15 10:54 2718人阅读 评论(0) 收藏 举报 dllmfcinterfaceparameterslibrarynull 方法1:   在VC上new一个名为dll的MFC DLL工程. 第一步,创建一个interface.h文件来定义接口,代码如下: //file interface.h #ifndef _INTERFACE_H_ #define _INTERFACE_H_ interface ITest { virtual int Print(

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

1. DLL的概念DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用.静态链接库与动态链接库的区别:(1)静态链接库与动态链接库都是共享代码的方式.静态链接库把最后的指令都包含在最终生成的EXE文件中了:动态链接库不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件.(2) 静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库.

C++ DLL导出类 知识大全

在公司使用C++ 做开发,公司的大拿搭了一个C++的跨平台开发框架.在C++开发领域我还是个新手,有很多知识要学,比如Dll库的开发. 参考了很多这方面的资料,对DLL有一个基本全面的了解.有一个问题让我有点困惑,普通的导入导出C++类的方式都是使用_declspec(dllexport) /_declspec(dllimport)来导入导出类,但是在公司的开发中我们没有导入导出,而是定义了一些只有纯虚函数的抽象类,然后定义了一个工厂类,将这个工厂类注册到框架的服务中心中,使用时从服务中心拿到这

浅谈Windows中DLL导出类

一般的DLL导出类方法,一个简单的例子: dllExample.h: 1 #pragma once 2 3 #ifdef DLL_EXPORTS 4 #define DLL_API __declspec(dllexport) 5 #else 6 #define DLL_API __declspec(dllimport) 7 #endif 8 9 class DLL_API ExportClass 10 { 11 pirvate: 12 int x; 13 public: 14 void foo(

编写DLL所学所思(2)——导出类

2011.10.6 烛秋             http://www.cnblogs.com/cswuyg/archive/2011/10/06/DLL2.html 一.导出类的简单方式 这种方式是比较简单的,同时也是不建议采用的不合适方式. 只需要在导出类加上__declspec(dllexport),就可以实现导出类.对象空间还是在使用者的模块里,dll只提供类中的函数代码.不足的地方是:使用者需要知道整个类的实现,包括基类.类中成员对象,也就是说所有跟导出类相关的东西,使用者都要知道.通

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

因为模板是在编译的时候根据模板参数实例化的,实例化之后就像一个普通的类(函数),这样才有对应的二进制代码;否则,没有模板参数,那么编译器就不知道怎么生成代码,所以生成的DLL就没有办法导出模板了.但是根据MSDN的描述,可以导出模板类的实例化后的代码(注意:这里不是指实例化模板类的一个对象),比如 template<typename T> class singleton,那么可以导出singleton<MyClass>或者其他已知类型的类代码.详见: http://support.

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

由于使用别人的Dll,导出的是一个实体类,在C#里封送很难,百度下,有个朋友回复一篇英文的,虽然不一定使用,但可以作为一个知识点,现把原文贴下: c#调用C++写的dll导出类,包含继承,重载等详细介绍(转载)忘了出处Inheriting From a Native C++ Class in C# Hi, this is Jim Springfield, an architect on the Visual C++ team.  I have blogged in the past about