前言
前一篇文章,我们介绍了erpc是何物,以及不同环境下如何编译erpc。今天,我们通过两个小demo开启erpc之旅。
注:以下均在 Linux 系统环境中操作。
你好 eRPC
编辑IDL文件
打开终端,进入工作路径。
新建文本文件,重命名保存为“hello.erpc”。编辑文件,添加内容:
program hello
enum lockErrors
{
ERR_OK = 0,
ERR_OUTMEM,
ERR_MAX,
}
interface Hello {
sayHello(binary txInput) -> binary
}
注:IDL语法见下篇文章,这里定义了一个叫“hello”的应用程序,只是定义了一个“sayHello”调用api
生成应用代码
执行命令erpcgen hello.erpc。生成四个文件“hello client.cpp”、“hello .h”、“hello_server.cpp”、“hello_server.h”。
新建并编辑源码文件“client.cpp”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <erpc_client_setup.h>
#include <erpc_port.h>
#include "hello.h"
static void free_binary_t_struct(binary_t *data)
{
if (data->data) {
erpc_free(data->data);
}
}
int main(int argc, char *argv[])
{
erpc_transport_t transport = erpc_transport_tcp_init("127.0.0.1", 5555, false);
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
erpc_client_init(transport, message_buffer_factory);
char *msg = "hello erpc!";
binary_t b = {(uint8_t *)msg, (uint32_t)strlen(msg)};
binary_t *resp = sayHello(&b);
if (resp != NULL) {
char *buf = (char *)malloc(resp->dataLength + 1);
strncpy(buf, (const char *)resp->data, resp->dataLength);
buf[resp->dataLength] = '\0';
printf("respond: %s\n", buf);
free_binary_t_struct(resp);
free(buf);
}
erpc_transport_tcp_close();
return 0;
}
最后首先创建初始化服务的erpc客户端打印程序,然后调用”函数远程传参是一个远程数据结构,给一个数据结构(这里填充的字符串的字符串执行响应结果。
新建并编辑源码文件“server.cpp”
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <erpc_server_setup.h>
#include "hello_server.h"
binary_t *sayHello(const binary_t input)
{
struct timeval t_val;
struct tm tm_l = NULL;
time_t tim_t;
size_t len = 0;
char *buf;
printf("ServerHello called\n");
buf = (char *)malloc(input->dataLength + 21);
strncpy(buf, (const char )input->data, input->dataLength);
gettimeofday(&t_val, NULL);
tim_t = t_val.tv_sec;
tm_l = localtime(&tim_t);
len = strftime(&buf[input->dataLength], 21, "@%Y-%m-%d %H:%M:%S", tm_l);
len = strlen(buf);
printf("data: %lu; %s\n", len, buf);
return new binary_t{(uint8_t)buf, (uint32_t)len};
}
int main(int argc, char *argv[])
{
erpc_transport_t transport = erpc_transport_tcp_init("127.0.0.1", 5555, true);
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
erpc_server_init(transport, message_buffer_factory);
erpc_add_service_to_server(create_Hello_service());
while(1){
erpc_server_run();
}
erpc_transport_tcp_close();
return 0;
}
首先创建服务端 erpc 服务,然后调用 erpc_server_run”等待客户端的调用请求。有客户端调用“sayHello”函数时,“服务端将接收到的参数是然后的渲染本地时间,再给客户端的渲染时间”。端传输给服务端的,返回值是服务端生成返回给了客户端。
注:服务端应用程序必须sayHello。这里是“hello.erpc”文件中定义的sayHello函数的实现
编译应用程序
分别执行和下面的命令,生成服务端程序。
g++ -Wall -I. -I/usr/local/include/erpc -L/usr/local/lib hello_server.cpp server.cpp -lerpc -lpthread -o server
g++ -Wall -I. -I/usr/local/include/erpc -L/usr/local/lib hello_client.cpp client.cpp -lerpc -lpthread -o client
注:其中的erpc库编译见上篇文章。
执行程序
在一个终端里执行./server,另外一个终端里./client打印执行。正常运行端
ServerHello called
data: 31; hello erpc!@2022-08-17 14:26:16
客户端响应
respond: hello erpc!@2022-08-17 14:26:16
运行结果符合预期。
矩阵乘法方程
编辑IDL文件
矩阵.erpc
program matrix;
const int32 matrix_size = 5;
type Matrix = int32[matrix_size][matrix_size];
interface MatrixServer
{
matrixMultiply(in Matrix matrix1, in Matrix matrix2, out Matrix result) -> void
}
执行命令erpcgen matrix.erpc。
客户端应用程序源码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <erpc_client_setup.h>
#include <erpc_port.h>
#include "matrix.h"
int main(int argc, char *argv[])
{
erpc_transport_t transport = erpc_transport_tcp_init("127.0.0.1", 5555, false);
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
erpc_client_init(transport, message_buffer_factory);
Matrix matrix1, matrix2, result = {{0}};
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
matrix1[i][j] = j+1;
matrix2[i][j] = j+1;
}
}
printf("===== Matrix #1 =====\n");
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
printf("%08d ", matrix1[i][j]);
}
printf(";\n");
}
printf("===== Matrix #2 =====\n");
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
printf("%08d ", matrix2[i][j]);
}
printf(";\n");
}
// Call remote function matrixMultiply
matrixMultiply(matrix1, matrix2, result);
printf("===== Result Matrix =====\n");
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
printf("%08d ", result[i][j]);
}
printf(";\n");
}
erpc_transport_tcp_close();
return 0;
}
客户端初始化了两个 5x5 的值矩阵,并把这两个矩阵的值打印输出。调用“matrixMultiply”然后把计算结果矩阵的打印输出。
服务端程序源码
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <erpc_server_setup.h>
#include "matrix_server.h"
void matrixMultiply(Matrix matrix1, Matrix matrix2, Matrix result)
{
int i, j, k;
printf("===== Matrix #1 =====\n");
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
printf("%08d ", matrix1[i][j]);
}
printf(";\n");
}
printf("===== Matrix #2 =====\n");
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
printf("%08d ", matrix2[i][j]);
}
printf(";\n");
}
memset(result, 0, sizeof(Matrix));
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
for (k = 0; k < 5; k++) {
result[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
}
int main(int argc, char *argv[])
{
erpc_transport_t transport = erpc_transport_tcp_init("127.0.0.1", 5555, true);
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
erpc_server_init(transport, message_buffer_factory);
erpc_add_service_to_server(create_MatrixServer_service());
while(1){
erpc_server_run();
}
erpc_transport_tcp_close();
return 0;
}
“matrixMultiply”函数远程实现,计算结果结果里。
注:服务端应用程序必须matrixMultiply执行。这里是“matrix.erpc”文件中定义的matrixMultiply函数的实现
编译并运行
客户端有打印信息输出
$ ./client.exe
===== Matrix #1 =====
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
===== Matrix #2 =====
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
00000001 00000002 00000003 00000004 00000005 ;
===== Result Matrix =====
00000015 00000030 00000045 00000060 00000075 ;
00000015 00000030 00000045 00000060 00000075 ;
00000015 00000030 00000045 00000060 00000075 ;
00000015 00000030 00000045 00000060 00000075 ;
00000015 00000030 00000045 00000060 00000075 ;
改变两个矩阵值,响应的矩阵乘结果 #1 #2 也会改变。
结束语
本篇文章通过这两个小演示演示了 eRPC 的使用。
首先编辑eRPC的IDL语言脚本文件;然后生成代码;最后编写客户端和服务端的代码。
当调用sayHello或者调用matrixMultiply函数的过程时,就像调用本地的函数一样,其他函数执行可能是本机的另外一个进程或者网络内计算机上运行的程序。
本文没有讲解我的语法格式。下一篇,后面一篇,备用多的讲讲讲eRPC中使用的IDL语法格式。
原作者:出出啊