c++ RMI demo(使用RCF库)

作业要求

下载RCF库并编译成静态库/动态库
宿主机操作系统:ubuntu

1
2
wget https://www.deltavsoft.com/downloads/RCF-3.2.413.tar.gz # 下载RCF压缩包
tar xvf RCF-3.2.413.tar.gz # 解压到本地文件夹

在/root/code/rcf/RCF-3.2.413文件夹下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
g++ -I include/  src/RCF/RCF.cpp -lpthread -ldl -luuid -c # 生成obj文件
# -l:链接第三方库 -I:头文件目录 -c只进行 预处理, 编译,汇编操作,生成.o (.obj)文件,不进行链接。

报错fatal error: uuid/uuid.h: No such file or directory
sudo apt-get install uuid-dev # 安装uuid-devuuid-dev
# 重新运行g++命令成功
mkdir lib # 创建lib文件夹,存放静态库与动态库文件

# 生成静态库
# 将所有.o文件打包为静态库,r将文件插入静态库中,c创建静态库,不管库是否存在,s写入一个目标文件索引到库中
ar rcs librcf.a RCF.o
mv librcf.a lib/
mv RCF.o lib/RCF_static.o


# 生成动态库
g++ -I include/ src/RCF/RCF.cpp -lpthread -ldl -luuid -c -fPIC # 参数-fPIC表示生成与位置无关代码
g++ -shared -o librcf.so RCF.o
mv librcf.so lib/
mv RCF.o lib/RCF_share.o

仿照/root/code/rcf/RCF-3.2.413/demo文件夹下的demo编写RMI程序

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// interface.h
#pragma once
#include <string>
#include <RCF/RCF.hpp>

RCF_BEGIN(I_Translate, "I_Translate")
RCF_METHOD_R1(std::string, Translate, const std::string &);
RCF_END(I_Translate);

// server.cpp
#include <iostream>
#include <string>
#include <map>

#include "interface.h"

class Translator
{
public:
std::string Translate(const std::string &str)
{
if(word_list_.count(str)!=0){
return word_list_[str];
}
return {};
}
void InsertSampleData()
{
word_list_.insert({"Afghanistan", "阿富汗"});
word_list_.insert({"Denmark", "丹麦"});
word_list_.insert({"Egypt", "埃及"});
word_list_.insert({"Finland", "芬兰"});
word_list_.insert({"Korea (South)", "韩国"});
word_list_.insert({"Kuwait", "科威特"});
}

private:
std::map<std::string, std::string> word_list_;
};

int main()
{
RCF::RcfInit rcfInit;

std::string networkInterface = "0.0.0.0";
int port = 50001;
std::cout << "Starting server on " << networkInterface << ":" << port << "." << std::endl;

// Start a TCP server, and expose DemoService.
Translator translator;
translator.InsertSampleData();
RCF::RcfServer server(RCF::TcpEndpoint(networkInterface, port));
server.bind<I_Translate>(translator);
server.start();

std::cout << "Press Enter to exit..." << std::endl;
std::cin.get();

return 0;
}

// client.cpp
#include <iostream>
#include <string>

#include "interface.h"

int main()
{
RCF::RcfInit rcfInit;

try
{

std::string networkInterface = "127.0.0.1";
int port = 50001;
std::cout << "Connecting to server on " << networkInterface << ":" << port << "." << std::endl;

// Make the call.
auto remotes_obj = RcfClient<I_Translate>(RCF::TcpEndpoint(networkInterface, port));
std::string input_string;
std::string translate_res;
while (true)
{
std::cout << "输入需要查询的英文单词,按q结束查询" << std::endl;
std::cin >> input_string;
if (input_string == "q")
{
break;
}
translate_res = remotes_obj.Translate(input_string).get();
if (translate_res == "")
{
std::cout << "词汇表中未存该单词" << std::endl;
}
else
{
std::cout << translate_res << std::endl;
}
}
}
catch (const RCF::Exception &e)
{
std::cout << "Caught exception:\n";
std::cout << e.getErrorMessage() << std::endl;
return 1;
}

return 0;
}

编译运行

1
2
3
4
5
6
7
8
# 使用静态库
g++ client.cpp /root/code/rcf/RCF-3.2.413/lib/librcf.a -I /root/code/rcf/RCF-3.2.413/include/ -o client_static -lpthread -ldl -luuid
g++ server.cpp /root/code/rcf/RCF-3.2.413/lib/librcf.a -I /root/code/rcf/RCF-3.2.413/include/ -o server_static -lpthread -ldl -luuid


# 使用动态库
g++ client.cpp /root/code/rcf/RCF-3.2.413/lib/librcf.so -I /root/code/rcf/RCF-3.2.413/include/ -o client_share -lpthread -ldl -luuid
g++ server.cpp /root/code/rcf/RCF-3.2.413/lib/librcf.so -I /root/code/rcf/RCF-3.2.413/include/ -o server_share -lpthread -ldl -luuid



突然想到以上能成功的原因是不是因为interface.h中只使用了RCF.hpp,实际上是不是应该将所有源文件编译成obj文件,而后打包成静态库/动态库呢?以后再用到这个库时再看,不过打包成库的步骤差不多,也没有太大问题
参考博客
RCF的使用
Linux基础——gcc编译、静态库与动态库(共享库)