以前的关于动态链接库的写法多是直接采用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 description
*/
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++中函数模板与类模板的简单使用
- java的character用法_Java中Character类的使用方法
- 转载 Struts2之------Action类中的get,set方法和execute方法的使用规范和使用流程(规范是没有理由的,必须遵守!!!)
- C++中string的用法 string字符串的使用方法
- C/C++中动态链接库的创建和调用
- String类中的concat方法的使用
- C++面向对象-类的基本使用方法
- 使用dlopen和dlsym来使用C++中的类
- 4.编写Java应用程序。首先,定义一个时钟类——Clock,它包括三个int型 成员变量分别表示时、分、秒,一个构造方法用于对三个成员变量(时、分、秒) 进行初始化,还有一个成员方法show()用于显示时钟对象的时间。其次,再定义 一个主类——TestClass,在主类的main方法中创建多个时钟类的对象,使用这 些对象调用方法show()来显示时钟的时间。
- C++调用C#dll类库中的方法(非显性COM)