关闭

DLL导出类

标签: dll
99人阅读 评论(0) 收藏 举报
分类:

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()来调用类里面的方法和属性
完成
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:33199次
    • 积分:897
    • 等级:
    • 排名:千里之外
    • 原创:44篇
    • 转载:26篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论