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

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

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

编译速度很快。

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

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

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

72f514e1cb5fb5df6eacf30c2f7c0912.png

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

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

fafa0930f530a3cda4c66eb2d3d1912c.png

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

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

否则的__declspec(dllimport)

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

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

简单点就是 clsss __declspec(dllexport) XTCP

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

9f8080ab5c839070266bc24eade20259.png

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

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

6356e86f90809ed33c606c470dfc64db.png

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

6a3f6d1d84873ed6df7705d3ed1e5256.png

改变生成的lib文件位置

3156de4d152be246434ce0b70072cbbc.png

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

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

虽然他是dll文件。

11391fef82db55e7d9f041206219b3e2.png

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

e24ebab375e1d706e9e608485dbd4620.png

我们测试一下:

创建一个新的项目

edbec76b24609991728e8a5b3b9e4c80.png

1 包含XTCP.h所在的目录

a2175a6cc8568636bd3398ab64c0c256.png

2 .lib所在的目录

cecac4bd939b78404f974b9def0aab12.png

3加载lib文件

4960d4ca4f87a0799746b8c5516669f7.png

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

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

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

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

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

7b8d33abf802114d472c2724f3e54b1a.png

测试代码如下: 完全没有任何问题#include "XTCP.h"

#include 

#include 

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.cppXTCP.h

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

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

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

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

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

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

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

成功生成

10d5de63dafdb66e006e1ec3bf07e94b.png

#include "XTCP.h"

#include 

#include 

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的代码就行,然后用

f63decf32aded105d89991113be14645.png

在写一个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的路径

第二行是执行的程序

7a0c52a0efd363cbbd828105860cd473.png

命令: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,生成成功后,libxsocket.so:XTCP.cpp XTCP.h

g++ $+ -o $@ -fpic -shared -std=c++11

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

但是linux用的是so库。

server:server.cpp

g++ $+ -o $@ -I../xsocket -std=c++11 -lpthread -lxsocket -L../xsocket

92bc45767a767792a223014b7f74c1d0.png

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐