以前的关于动态链接库的写法多是直接采用extern 'C'的方式来实现,但是如果采用类来编写就会出现问题了,因为类在编译时是不能确定入口点位置的。这样就产生了问题。怎么来使用呢?前两个方法是在linux下直接使用普通函数调用的方法来实现的。后边的是在vc++中使用宏来对入口点动态调整输入输出__declspec(dllimport)和__declspec(dllexport)
方法1: 把类作为参数传入 接口函数中去:
//----------------------- myclass.h 文件-----------------
#ifndef MYCLASS_H
#define MYCLASS_H
class myclass
{
public:
myclass(){}
~myclass() {}
public:
int sum(int a,int b);
private:
int _a;
int _b;
};
#ifdef SHARED
int (*sum)(myclass *my,int a,int b);
#else
int sum(myclass *my,int a,int b);
#endif
#endif // MYCLASS_H
//----------------------- myclass.cpp 文件-----------------
#include "myclass.h"
int myclass::sum(int a,int b)
{
int c = a + b;
return c;
}
int sum(myclass *my,int a,int b)
{
int c = my->sum(a,b);
return c;
}
//----------------------- my.cpp 测试文件 文件-----------------
#include <iostream>
#include <dlfcn.h>
#define SOFILE "./my.so"
#define SHARED
#include "myclass.h"
using namespace std;
int main(int argc, char *argv[])
{
myclass my;
void *dp;
char *error;
cout<<"动态链接库应用示范"<<endl;
dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库 */
if (dp==0) /* 若打开失败则退出 */
{
cout<<"若打开失败则退出 dlopen"<<endl;
return(1);
}
sum=(int(*)(myclass *my,int a,int b))dlsym(dp,"sum"); /* 定位求和函数 */
error=dlerror(); /* 检测错误 */
if (error) /* 若出错则退出 */
{
cout<<"若出错则退出 :定位求和函数 sum"<<endl;
return(1);
}
int a = 10;
int b = 100;
int c = sum(&my,a,b); /* 调用此共享函数 */
cout<<"c = "<<endl;
system("PAUSE");
return 0;
}
编译:
g++ myclass.h myclass.cpp -shared -o my.so
g++ my.cpp -rdynamic -lds -o my.exe
**********************************************************************
方法2: 声名一个类的全局变量 然后在接口中使用这个全局变量:
//----------------------- myclass.h 文件-----------------
#ifndef MYCLASS_H
#define MYCLASS_H
/*
* No de
scription
*/
class myclass
{
public:
myclass(){}
~myclass() {}
public:
int sum(int a,int b);
private:
int _a;
int _b;
};
//声名一个类的全局变量 然后在接口中使用这个全局变量:
extern myclass my;
#ifdef SHARED
int (*sum)(int a,int b);
#else
int sum(int a,int b);
#endif
#endif // MYCLASS_H
//----------------------- myclass.cpp 文件-----------------
#include "myclass.h"
int myclass::sum(int a,int b)
{
int c = a + b;
return c;
}
int sum(int a,int b)
{
int c = my.sum(a,b);
return c;
}
//----------------------- my.cpp 测试文件 文件-----------------
#include <iostream>
#include <dlfcn.h>
#define SOFILE "./my.so"
#define SHARED
#include "myclass.h"
using namespace std;
int main(int argc, char *argv[])
{
//myclass my;
void *dp;
char *error;
cout<<"动态链接库应用示范"<<endl;
dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库 */
if (dp==0) /* 若打开失败则退出 */
{
cout<<"若打开失败则退出 dlopen"<<endl;
return(1);
}
sum=(int(*)(int a,int b))dlsym(dp,"sum"); /* 定位求和函数 */
error=dlerror(); /* 检测错误 */
if (error) /* 若出错则退出 */
{
cout<<"若出错则退出 :定位求和函数 sum"<<endl;
return(1);
}
int a = 10;
int b = 100;
int c = sum(a,b); /* 调用此共享函数 */
cout<<"c = "<<endl;
system("PAUSE");
return 0;
}
编译:
g++ myclass.h myclass.cpp -shared -o my.so
g++ my.cpp -rdynamic -lds -o my.exe
*************************************************************
方法三:
在 DLL 的输出头文件中用上:
#ifdef MYLIBAPI
#else
#define MYLIBAPI __declspec(dllimport)
#endif
在 DLL 的 cpp 文件中,引用头文件的前面加上:
#define MYLIBAPI __declspec(dllexport)
注意,这时候 extern “C” 已经没有了。因为我们要输出的就是 C++ 类。
同时,在类的头文件中,类的定于前面写上:
class MYLIBAPI classname {
}
这就 OK 啦。
*************************************************
#include <iostream>
using namespace std;
class DLLClass{
public:
// exported member function
__declspec(dllexport) void functionA(void)
{
cout << "In Function A of the exported function" << endl;
return;
}
};
// exported class
class __declspec(dllexport) ExportDLLClass{
public:
void functionB(void)
{
cout << "In Function B of the exported class" << endl;
return;
}
};
// exported instance of the DLLClass
__declspec(dllexport) DLLClass test;
保存成TestDLL.cpp然后进行编译。呵呵,因为是用Editplus写的代码,所以要手动编译哦^^
我用的是VS 2005的CL编译接口CL.exe。在Cmd下:CL/c TestDLL.cpp
此时就生成了TestDLL.obj,然后进行链接:link TestDLL.obj /DLL
此时将生成TestDLL.dll,TestDll.exp,TestDll.lib三个文件
工作暂告一个段落。。。。
然后开始写调用TestDLL.dll的CallDLL.exe文件:
class DLLClass{
public:
// imported member function
__declspec(dllimport) void functionA(void);
};
// imported class
class __declspec(dllimport) ExportDLLClass{
public:
void functionB(void);
};
// imported instance of the DLLClass
__declspec(dllimport) DLLClass test;
int main(void)
{
ExportDLLClass TestClass;
test.functionA();
TestClass.functionB();
return 0;
}
分享到:
相关推荐
将现有的C++类转换成dll动态链接库 C++类转换成dll dll动态链接库
鉴于devc++资料较少,本文介绍了用devc++制作和调用dll的一般方法。是笔者自己的整理,希望对大家有用。
便于在C#调用C++的动态链接库dll代码实例
c++ 动态链接库,包括传统方法,纯c方法导出函数和导出类,使用导出的类和MFC类,导入即用,不含糊!
C#调用C++中动态链接库DLL中的结构体使用方法,范例。。。
C++动态链接库编程深入浅出,动态链接库的建立与调用。
lua动态链接库的编译 c++调用lua的的方法 linux中调用lua的环境配置
创建和使用动态链接库 (C++)C#调用 创建和使用动态链接库 (C++)C#调用 创建和使用动态链接库 (C++)C#调用
实现了一个简单的动态链接库的使用过程,注意在windows平台vc++中使用
c++ 静态链接库 动态链接库示例 静态链接库 动态链接库示例
学习C++时的笔记,包括了C++动态链接库的创建与使用,还包括了C++中的调用约定等内容
通过C#调用C++的动态链接库,示例中展示了多种在C#程序中调用C++动态链接库的情况,特别是对于各种类型参数的传递形式,并给出了哪些传递方式能成功。
详细描述C++动态链接库与静态链接库的创建以及原理,内附测试demo.
反编译软件,可将动态链接库反编译回c/c++
C++动态链接库读写文件
动态链接库的实现动态链接库的实现动态链接库的实现动态链接库的实现动态链接库的实现动态链接库的实现
解决系统dll动态链接库或者c++依赖库缺失, 解决Mysql因缺少系统依赖库导致的安装失败问题....
详细讲述了在vc下动态链接库的开发和使用以及测试
学写带接口类的动态链接库,包括文档,类,以及调用
vs2017 C++动态链接库的创建和调用,在VS2017下创建C++动态库(编译时去掉预编译头),把.h ,lib文件拷入新建测试工程目录下并添加到该工程中,dll文件加到运行目录下