将一个类封装到dll和linux的so
这篇博客里封装了一个tcp网络类,每次开发我门只需要加载这个动
态库,这个模块.就可以使用里面的函数.使用动态库的好处就是
编译速度很快。
1首先添加到windows的dll动态库里面.
新建一个VS里的win32控制台程序。然后选择动态化
选择导出符合,导出符合的好处就是,有一些宏已经定义好了
然后添加现有项,把之前封装的XTCO封装进来。
在Windows中,直接这样是不行的,我们要添加宏定义
添加到这个类的最顶部,这个定义的意思是:如果定义了
这个宏,我就把XTCP定义成 __declspec(dllexport)
否则的__declspec(dllimport)
当一个新项目调用他的时候,他就是没有定义 那么就是
__declspec(dllimport) 也就是导入的状态。
简单点就是 clsss __declspec(dllexport) XTCP
如果是用户调用的时候 clsss __declspec(dllimport) XTCP
这个dll项目在VS里的预处理器是早就预定义好的
当你创建一个新的c++项目是不会有这个定义的
平台工具集要改成,WIN ..xp否则XP不能用这个dll
改变生成的lib文件位置
工作目录都改成../../bin,
因为你执行调试的时候会在这个目录找生成的文件
虽然他是dll文件。
生成成功是没有任何问题的。
我们测试一下:
创建一个新的项目
1 包含XTCP.h所在的目录
2 .lib所在的目录
3加载lib文件
当他调用这个的时候会把这个lib文件编译到exe执行文件里
通过这个lib加载dll, 调用里边的函数
测试部分------------------------------------
我们直接绑定就好了,因为在Bind函数里直接调用了。
CreateSocket()函数,他会对调用他的对象里的m_sock进行赋值
测试代码如下: 完全没有任何问题
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
成功生成
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的代码就行,然后用
在写一个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的路径
第二行是执行的程序
命令: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
|
本文转自超级极客51CTO博客,原文链接:http://blog.51cto.com/12158490/1947885,如需转载请自行联系原作者