关闭

DLL导出类

标签: dll
170人阅读 评论(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
查看评论

C++ DLL导出类

在公司使用C++ 做开发,公司的大拿搭了一个C++的跨平台开发框架。在C++开发领域我还是个新手,有很多知识要学,比如Dll库的开发。    参考了很多这方面的资料,对DLL有一个基本全面的了解。有一个问题让我有点困惑,普通的导入导出C++类的方式都是使用_declspec(dl...
  • JieTouLangRen
  • JieTouLangRen
  • 2013-11-02 11:22
  • 9973

DLL导出类和导出函数

1、动态库DLL中的类或者函数有时候要被其他的库调用,因此需要被其他库调用的类或者函数需要进行导出。 2、首先编写需要导出的DLL,新建一个工程设置应用程序类型为DLL 3、类的代码如下 头文件 #pragma once #define EX_PORT __declspec(dl...
  • goodluckMT
  • goodluckMT
  • 2016-09-28 16:05
  • 3449

动态链接库(DLL)总结---从DLL中导出类(6)

我们创建一个工程动态链接库,名称为DLL1,然后在DLL1.h中添加代码如下: #ifdef DLL1_API_IMP #else #define DLL1_API_IMP __declspec(dllimport) #endif //导出类 class DLL1_API_IMP Tes...
  • oBuYiSeng
  • oBuYiSeng
  • 2015-12-01 08:50
  • 1803

DLL 导出类必须要导出接口

假设下面情形:某DLL为客户代码导出了下面类class __declspec(dllexport) CTest{public : void print1() {  printf("print1");  c[1023] =...
  • Blue_Dream_
  • Blue_Dream_
  • 2008-04-29 11:12
  • 1335

C++动态库(Dll)的制作,导出类

1、完成类的封装: 如:CMyTestClass类/// CMyTestClass.h头文件中 /************************************************************************ * Copyright(c) 2000-2013 C...
  • bao_bei
  • bao_bei
  • 2016-06-03 16:24
  • 2750

DLL 导出类的问题

使用DLL的一个比较严重的问题就是编译器之间的兼容性问题。不同的编译器对c++函数在二进制级别的实现方式是不同的。所以对基于C++的DLL,如果编译器­不同就有很麻烦的。如果创建的是MFC扩展DLL,就不会存在问题,因为它只能被动态连接到MFC的客户应用程序。这里不是本文讨论的重点。...
  • flyoxs
  • flyoxs
  • 2010-04-28 11:07
  • 4023

C++ DLL总结—静动态调用、导出类

1、 DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数、变量或类。这些可以直接拿来使用。 静态链接库与动态链接库的区别: (1)静态链接库与动态链接库都是共享代码的方式。静态链接库把最后的指令都包含在最终生成的EXE文件中了;动态链接...
  • WaitForFree
  • WaitForFree
  • 2014-07-19 11:03
  • 4347

动态调用有源码的DLL中的导出类

前言 动态调用DLL的好处: * 防止静态调用DLL不在报错 * 实现插件化编程 有源码的DLL可以添加接口 可以在DLL中加入建立类指针和释放类指针的接口, 不用自己去调用类构造和析构函数 对于虚函数的调用,可以通过类指针直接调用,因为可以在虚函数表中直接找到虚函数地址 对于非虚函数的调用...
  • LostSpeed
  • LostSpeed
  • 2016-03-11 00:14
  • 868

DLL编程——Win32导出DLL类

1、新建一个Win32 DLL 工程 添加头文件到工程中,编写自定义DLL导出类: #ifndef DLLCLASS_H_ #define DLLCLASS_H_ #include using namespace std; #define DLL_EXPORT _declspec(dllexpor...
  • mfcing
  • mfcing
  • 2012-04-10 22:12
  • 3587

C++ DLL 创建实例 导出类和函数

起初直接把子__declspec(dllexport) 放在类声明的地方. 发生 warning C4273 DLL 链接不一致错误. 想了挺长时间才意识到是生成lib时并头文件和原文件中对函数的名字解析名字不一样而产生的.  才想到要定义一个宏. 有点感叹知识不用会也会老的....
  • xiaojun111111
  • xiaojun111111
  • 2015-12-12 09:23
  • 328
    个人资料
    • 访问:62478次
    • 积分:1219
    • 等级:
    • 排名:千里之外
    • 原创:57篇
    • 转载:32篇
    • 译文:0篇
    • 评论:13条
    文章分类
    最新评论