将一个类封装到dll和linux的so

简介:

         将一个类封装到dll和linux的so


这篇博客里封装了一个tcp网络类,每次开发我门只需要加载这个动

态库,这个模块.就可以使用里面的函数.使用动态库的好处就是

编译速度很快。



  1首先添加到windows的dll动态库里面.

新建一个VS里的win32控制台程序。然后选择动态化

选择导出符合,导出符合的好处就是,有一些宏已经定义好了

wKioL1lpyhjCSOFyAABFEvX8cDo621.png-wh_50

然后添加现有项,把之前封装的XTCO封装进来。


在Windows中,直接这样是不行的,我们要添加宏定义

wKiom1lpy5jhrPkpAADv-g79eck008.png-wh_50


添加到这个类的最顶部,这个定义的意思是:如果定义了

这个宏,我就把XTCP定义成  __declspec(dllexport)

否则的__declspec(dllimport)

当一个新项目调用他的时候,他就是没有定义 那么就是

__declspec(dllimport) 也就是导入的状态。

简单点就是 clsss __declspec(dllexport) XTCP

如果是用户调用的时候 clsss __declspec(dllimport) XTCP


wKioL1lpzLqjGBRKAAAqKDmumdQ908.png-wh_50


这个dll项目在VS里的预处理器是早就预定义好的

当你创建一个新的c++项目是不会有这个定义的

wKioL1lpzRXziyYXAAGv9h4t-pE425.png-wh_50


平台工具集要改成,WIN ..xp否则XP不能用这个dll

wKioL1lp0MrAOmDMAACuTZkN0U8359.png-wh_50


改变生成的lib文件位置

wKioL1lp0VuiiLcXAAAw1lkFcLw522.png-wh_50


工作目录都改成../../bin,

因为你执行调试的时候会在这个目录找生成的文件

虽然他是dll文件。


wKiom1lp0bfzU_1WAAAdxo7G400532.png-wh_50


生成成功是没有任何问题的。

wKioL1lp1HuDDd49AAGTC72fGKk936.png-wh_50


我们测试一下:

创建一个新的项目

wKiom1lp1S_TO4k2AACS1MOUnQE060.png-wh_50


1 包含XTCP.h所在的目录

wKiom1lp1uvRiJ7LAAAt2p0_ej4491.png-wh_50

2 .lib所在的目录  

wKioL1lp2NeycX0rAADZoUZtFJ4053.png-wh_50




3加载lib文件

wKiom1lp12vBn5_rAACtLNT1iO0506.png-wh_50


当他调用这个的时候会把这个lib文件编译到exe执行文件里

通过这个lib加载dll, 调用里边的函数



测试部分------------------------------------


我们直接绑定就好了,因为在Bind函数里直接调用了。

CreateSocket()函数,他会对调用他的对象里的m_sock进行赋值

wKiom1lp2iujVuIKAABMa5S7rk0874.png-wh_50

测试代码如下: 完全没有任何问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "XTCP.h"
#include <thread>
#include <string.h>
class  TcpThread
{
public :
//线程入口函数 创建一个
void  Main()
{
char  buf[1024];
for  (;;)
{
memset (buf, 0,  sizeof (buf));
int  recv_len = client.Recv(buf,  sizeof (buf) - 1);
if  (recv_len <= 0) break ;
if  ( strstr (buf,  "quit" ) != NULL)
{
char  re[] =  "quit success\n" ;
int  sendlen = client.Send(re,  strlen (re) + 1);
break ;
}
char  p_ok[] =  "ok\n" ;
int  sendlen = client.Send(p_ok,  strlen (p_ok));
printf ( "recv %s\n" , buf);
}
client.Close();
delete  this ;
}
//用户的socket
XTCP client;
};
int  main( int  argc, char  *argv[])
{
unsigned  short  port = 8081;
XTCP server;
server.Bind(port);
//单线程测试
for  (;;)
{
XTCP client = server.Accept();
//创建线程
TcpThread *th =  new  TcpThread();
th->client = client;
std:: thread  sthr(&TcpThread::Main, th);
// 释放主线程占用的资源
sthr.detach();
}
server.Close();
getchar ();
return  0;
}




     2添加到Linux的so文件中

创建一个makefile在windows进行编辑,使用文本编辑器打开

目标文件libxsocket.so:依赖文件:XTCP.cpp XTCP.h

用g++编译 $+(依赖项) -o $@(表示目标) -fpic(代码与位置无关)

(这样我门调用的时候,只有通过名字就能找到函数的定义,)

-shared(表示把他编程动态库)-std=c++11(动态库用到了c++11)

完整就是这样,输入make命令就会直接编译


注意Linux的文件你必须是lib开头.so结尾。当你在Linux里

用这个库的时候,只需要用中间这个名字就行了


1
2
libxsocket.so:XTCP.cpp XTCP.h
g++ $+ -o $@ -fpic -shared -std=c++11

注意的是一些宏定义在linux

可以用 来解决

#ifdef WIN32

#ifdef XSOCKET_EXPORTS

#define XSOCKET_API __declspec(dllexport)

#else

#define XSOCKET_API __declspec(dllimport)

#endif


#else

#define XSOCKET_API

#endif

成功生成

wKioL1lp4e7SGoIDAACMEsjT-l4788.png-wh_50



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "XTCP.h"
#include <thread>
#include <string.h>
class  TcpThread
{
public :
//线程入口函数 创建一个
void  Main()
{
char  buf[1024];
for  (;;)
{
memset (buf, 0,  sizeof (buf));
int  recv_len = client.Recv(buf,  sizeof (buf) - 1);
if  (recv_len <= 0) break ;
if  ( strstr (buf,  "quit" ) != NULL)
{
char  re[] =  "quit success\n" ;
int  sendlen = client.Send(re,  strlen (re) + 1);
break ;
}
char  p_ok[] =  "ok\n" ;
int  sendlen = client.Send(p_ok, strlen (p_ok));
printf ( "recv %s\n" , buf);
}
client.Close();
delete  this ;
}
//用户的socket
XTCP client;
};
int  main( int  argc, char *argv[])
{
unsigned  short  port = 8016;
XTCP mytcp;
//创建
mytcp.CreateSocket();
//绑定
if  (!mytcp.Bind(port))
return  -1;
for  (;;)
{
XTCP client = mytcp.Accept();
//创建线程
TcpThread *th =  new  TcpThread();
th->client = client;
std:: thread  sthr(&TcpThread::Main, th);
// 释放主线程占用的资源
sthr.detach();
}
mytcp.Close();
getchar ();
return  0;
}


用上面测试dll的代码就行,然后用

wKiom1lp5KiBUA7UAAA0A3ccqSs427.png-wh_50


在写一个makefile来编译他,用到linux的so文件

目标文件:依赖文件

tcpserver:server.cpp

g++ $+(依赖项) -o $@(目标项) -I../xsocket(XTCP.h头文件路径)

-std=c++11(c++11) -lpthread(线程库)

-lxsocket(使用libxsocket.so库文件,因为linux这个so文件,前面

必须要lib开头,尾部必须要.so结尾,用的时候只有中间的xsocket就行);

-L../xsocket so所在的路径

但是会有错误 我们写个脚本: vim run

里面填写路径

第一行是 so的路径

第二行是执行的程序

wKiom1lp6BvR9n4kAABClp88XuQ718.png-wh_50

命令:chmod +x run给他执行权限

然后./run执行一下


关于so 找不到的问题后续解决,

qq:2438746951






2017年7月7日补充: Linux  so的封装和测试

首先,有XTCP类:XTCP.h XTCP.cpp文件。

1生成so文件  makefile

libxsocket.so 是目标文件,XTCP.cpp XTCP.h是依赖文件

 g++是编译器,$+ 代表依赖文件,-o代表指定目标名称, 

$@代表目标文件, -fpic -shared是生成so库要加的命令

-std=c++11代表用到了c++11,生成成功后,

1
2
libxsocket.so:XTCP.cpp XTCP.h
         g++ $+ -o $@ -fpic -shared -std=c++11



测试程序的生成,测试代码上面以及写了,和dll测试一样的,

但是linux用的是so库。


1
2
server:server.cpp
         g++ $+ -o $@ -I../xsocket -std=c++11 -lpthread -lxsocket -L../xsocket


wKiom1lsHCDzcu_FAAA7kqrHTZQ631.png-wh_50








 本文转自超级极客51CTO博客,原文链接:http://blog.51cto.com/12158490/1947885,如需转载请自行联系原作者





相关文章
|
4天前
|
JSON 机器人 Linux
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
59 3
|
6月前
|
Linux
Linux查找多个文件、排除某类文件、匹配文件多处内容
Linux查找多个文件、排除某类文件、匹配文件多处内容
|
4天前
|
Linux
linux(二十八)磁盘管理类命令df、du和free查看磁盘和目录空间占用
linux(二十八)磁盘管理类命令df、du和free查看磁盘和目录空间占用
85 0
|
4天前
|
Ubuntu Linux Shell
mc实现目录同步并封装成Linux服务形式
mc实现目录同步并封装成Linux服务形式
15 1
|
4天前
|
Unix Shell Linux
在Linux和类Unix系统中,Shell提供了多种命令用于用户和权限管理
在Linux和类Unix系统中,Shell提供了多种命令用于用户和权限管理
38 4
|
4天前
|
安全 Unix Linux
【专栏】`rmdir`命令在Linux和类Unix系统中用于删除空目录,不适用于非空目录
【4月更文挑战第28天】`rmdir`命令在Linux和类Unix系统中用于删除空目录,不适用于非空目录。基本语法为`rmdir [options] directory...`,常用选项包括`-p`(递归删除空父目录)和`--ignore-fail-on-non-empty`(忽略非空目录错误)。与`rm -r`相比,`rmdir`更安全,适用于知道目录为空的情况。在自动化脚本和清理构建目录等场景中,`rmdir`能有效管理空目录。使用时确保目录为空,避免误删,必要时结合`ls`和`sudo`检查或提升权限。
|
4天前
|
监控 Unix Linux
在Linux和类Unix操作系统中,`top` 命令
在Linux和类Unix操作系统中,`top` 命令
32 2
|
4天前
|
Ubuntu Linux 定位技术
linux(十八)时间日期类相关命令
linux(十八)时间日期类相关命令
28 0
|
5月前
|
安全 Linux 网络安全
论文推荐| 面向虚拟地理环境的Linux平台地理分析模型服务化封装方法
论文推荐| 面向虚拟地理环境的Linux平台地理分析模型服务化封装方法
44 9
|
6月前
|
Linux
解决linux中因为安装软件踩坑系类---unbantu
解决linux中因为安装软件踩坑系类---unbantu
36 0