jsonrpc-c交叉编译测试

一、环境搭建

需要的资源如下:

libev,jsonrpc-c

https://codeload.github.com/enki/libev/zip/refs/heads/master

https://codeload.github.com/hmng/jsonrpc-c/zip/refs/heads/master

1.编译libev,jsonrpc

参考:编译jsonrpc

lib_make.sh

#!/bin/sh
# @Author: yyh
# @Date:   2023-03-13 12:55:16
# @Last Modified by:   yyh
# @Last Modified time: 2023-03-13 14:22:45
 
sudo mkdir ~/lib_srouce_code/
case $1 in
    "libev")  
        cp libev-master.zip ~/lib_srouce_code/
        cd ~/lib_srouce_code/
        unzip -x libev-master.zip -d ~/lib_srouce_code/
        cd ~/lib_srouce_code/libev-master
        if [ $2 = "ubuntu" ] ; then
            #ubuntu16.04
            sudo mkdir compile_result_ubuntu16/
            ./configure  --prefix=$(pwd)/compile_result_ubuntu16
        elif [ $2 = "mipsel" ]; then
            #mipsel
            sudo mkdir compile_result_mipsel/
            ./configure --prefix=$(pwd)/compile_result_mipsel --host=mipsel-openwrt-linux CC=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin/mipsel-openwrt-linux-gcc CXX=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin/mipsel-openwrt-linux-musl-g++
            `STAGING_DIR=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/`
        fi
        sudo make clean
        sudo make 
        sudo make install
    ;;
    "jsonrpc")
          cp jsonrpc-c-arma_stable.tar.gz ~/lib_srouce_code/
        tar -xzvf jsonrpc-c-arma_stable.tar.gz -C ~/lib_srouce_code/
        cd ~/lib_srouce_code/jsonrpc-c-arma_stable
        autoreconf -i
        if [[ $2 = "ubuntu" ]]; then
            #ubuntu16.04
            sudo mkdir compile_result_ubuntu16/
            ./configure --prefix=$(pwd)/compile_result_ubuntu16 --enable-shared
        # elif [[ $2 = "mipsel" ]]; then
        #     #mipsel
        #     sudo mkdir compile_result_mipsel/
        #     ./configure --prefix=$(pwd)/compile_result_mipsel --host=mipsel-openwrt-linux CC=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin/mipsel-openwrt-linux-gcc CXX=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin/mipsel-openwrt-linux-musl-g++
        #     `STAGING_DIR=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/`
        fi
        sudo make clean
        sudo make
        sudo make install
    ;;
    "install")   #先编译libev和jsonrpc-c,后install,编译目标环境需一致
        if [ $2 = "ubuntu" ]; then
            sudo mkdir ubuntu_test_code/
            sudo cp ~/lib_srouce_code/libev-master/compile_result_ubuntu16/* ./ubuntu_test_code -rf -p         #-p 保留源文件或目录的属性
            sudo cp ~/lib_srouce_code/jsonrpc-c-arma_stable/compile_result_ubuntu16/* ./ubuntu_test_code -rf -p
        elif [ $2 = "mipsel" ]; then
            sudo mkdir mipsel_test_code/
            sudo cp ~/lib_srouce_code/jsonrpc-c-arma_stable/src/*.c         ./mipsel_test_code -rf -p
            sudo cp ~/lib_srouce_code/jsonrpc-c-arma_stable/include/*.h     ./mipsel_test_code -rf -p
            sudo cp ~/lib_srouce_code/libev-master/compile_result_mipsel/*     ./mipsel_test_code -rf -p         #-p 保留源文件或目录的属性
            sudo cp ./mipsel_test_code/lib/libev.so.4.0.0  ./mipsel_test_code/lib/libev.so
            sudo cp ./mipsel_test_code/lib/libev.so.4.0.0  ./mipsel_test_code/lib/libev.so.4 
                        sudo cp ./mipsel_test_code/*.h   ./mipsel_test_code/include/
            # sudo cp ~/lib_srouce_code/jsonrpc-c-arma_stable/compile_result_mipsel/* ./mipsel_test_code -rf -p
        fi
    ;;
    # *)  echo '你没有输入 1 到 4 之间的数字'
    # ;;
esac


##./lib_make.sh libev mipsel
##./lib_make.sh install mipsel

##./lib_make.sh libev ubuntu
##./lib_make.sh jsonrpc ubuntu
##./lib_make.sh install ubuntu
 

2.交叉编译

./lib_make.sh libev mipsel
./lib_make.sh install mipsel

进入mipsel_test_code目录相关文件如下

在这里插入图片描述

二、编译并运行代码

在这里插入图片描述

1.makefile

CC=/opt/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin/mipsel-openwrt-linux-gcc

# LIBEV_DIR=/home/yyh/lib_srouce_code/libev-master/compile_result_mipsel
LIBEV_DIR=.
LIBEV_DIR=.
CFLAGS =  -I${LIBEV_DIR}/include -L${LIBEV_DIR}/lib 
LDAGS = -lev
 
TARGET = test

all:
    $(CC) -o $(TARGET) *.c $(CFLAGS)  $(LDAGS)


.PHONY:clean
clean:
    rm -rf *.o $(TARGET)

2.server.c

/*
* @Author: yyh
* @Date:   2023-03-11 16:00:39
* @Last Modified by:   yyh
* @Last Modified time: 2023-03-13 12:49:36
*/
#include   <stdio.h>
#include   <stdlib.h>
#include   <unistd.h>
#include   <errno.h>
#include   <string.h>
#include   <sys/types.h>
#include  <sys/socket.h>
#include  <netinet/in.h>
#include  <netdb.h>
#include  <arpa/inet.h>
#include  <sys/wait.h>
#include   <signal.h>
#include  "jsonrpc-c.h"

#define  PORT 1234   // the port users will be connecting to
#define  GET_KEY_SIZE 10    //键值对  键参数个数
#define  STRKEY_SIZE 20     //键的大小
#define  STRVAL_SIZE 20     //值的大小

struct  jrpc_server my_server;
cJSON *my_root;
cJSON * say_hello(  jrpc_context  * ctx, cJSON * params, cJSON *id) {

    return  cJSON_CreateString(  "Hello!"  );
}

cJSON * exit_server(  jrpc_context  * ctx, cJSON * params, cJSON *id) {
    jrpc_server_stop(&my_server);
    return  cJSON_CreateString(  "Bye!"  );
}

static char *get_key(char *s)//从一个json object对象中获取key
{
    char key[STRKEY_SIZE];
    char *pf,*pb;
    int len;
    pf=strchr(s, '\"');
    pb=strchr(pf+1, '\"');
    len = pb - pf - 1;
    memcpy(key, pf + 1, len);
    key[len]='\0';
    return strdup(key);
}

//echo "{\"method\":\"state_set\",\"params\":[{\"hello\":\"world\"}],\"id\":\"2\"}" | nc localhost 1234
cJSON * mystate_set(jrpc_context * ctx, cJSON * params, cJSON *id) { //设置键值对
    if(params == NULL){//获取参数失败
        ctx->error_code = 1;
        ctx->error_message=strdup("err_key)");
        ctx->data = strdup("err_value");
        return NULL;
    }
    int arrSize=cJSON_GetArraySize(params);//设置的获取参数个数
    
    int i,j;
    cJSON *vals,*dst_val;
    if(params->type == cJSON_Array){        
        for(i=0;i<arrSize;i++)  {           //获取每个参数对象
            vals = cJSON_GetArrayItem(params,i);
            if(vals->type == cJSON_Object){
                char *s = cJSON_PrintUnformatted(vals); //将一个jison object对象转为字符串
                char *key = get_key(s);                 //获取json object对象中的key
                cJSON *value = cJSON_GetObjectItem(vals,key);//通过key获取值
                if(value == NULL){                      
                    return cJSON_CreateString("bad key! bad value!");//格式错误
                }
                cJSON *item = cJSON_GetObjectItem(my_root,key);
                if(item != NULL)                         //如果原来json数据中存在该键值则删除
                    cJSON_DeleteItemFromObject(my_root,key);
                cJSON_AddItemToObject(my_root,key,cJSON_CreateString(value->valuestring));//添加新的键值对 
                free(s);
                free(key);
            }
        } 
    }
    return  cJSON_CreateString("set success!");
}

//echo "{\"method\":\"state_get\",\"params\":[\"hello\"],\"id\":\"1\"}" | nc localhost 1234
cJSON * mystate_get(  jrpc_context  * ctx, cJSON * params, cJSON *id) { //通过键获取值
    if(params == NULL){
        ctx->error_code = 1;
        ctx->error_message=strdup("err_key)");
        ctx->data = strdup("err_value");
        return NULL;
    }
    int arrSize=cJSON_GetArraySize(params);
    char *get_key[GET_KEY_SIZE];
    char *res_val[GET_KEY_SIZE];
    int i,j;
    cJSON *vals,*dst_val;
    if(params->type == cJSON_Array){
        for(i=0;i<arrSize;i++)  {
            vals = cJSON_GetArrayItem(params,i);
            if(vals->type == cJSON_String){
                get_key[i]=vals->valuestring;
            }
        } 
    }
    int count=0;
    for(j=0;j<i;j++)
    {
        dst_val=cJSON_GetObjectItem(my_root,get_key[j]);
        if(dst_val != NULL)
        {
            if(dst_val->type = cJSON_String)
            {
                res_val[count++]=dst_val->valuestring;
            }
        }
    }
    cJSON *res;
    res = cJSON_CreateArray();      //创建result参数返回对应值
    for(j=0;j<count;j++)
    {
        cJSON_AddItemToArray(res,cJSON_CreateString(res_val[j]));
    }

    if(cJSON_GetArraySize(res) == 0)    //没有找到对应的value
    {
        ctx->error_code = 1;
        ctx->error_message=strdup("no such value!");
        return NULL;
    }

    return  res;
}



int  main(  void  ) {
    jrpc_server_init(&my_server, PORT);
    //创建原始数据 json格式
    my_root = cJSON_CreateObject();
    cJSON_AddItemToObject(my_root,"jsonrpc",cJSON_CreateString("2.0"));
    cJSON_AddItemToObject(my_root,"method",cJSON_CreateString("DeviceUpLoadInfo"));
    cJSON_AddItemToObject(my_root,"id",cJSON_CreateString("76BFCDDE4D2C"));
    cJSON_AddItemToObject(my_root,"params",cJSON_CreateString("src"));
    cJSON_AddItemToObject(my_root,"ip",cJSON_CreateString("192.168.5.148"));
    cJSON_AddItemToObject(my_root,"time",cJSON_CreateString("2023-3-1 18:02:41"));
    cJSON_AddItemToObject(my_root,"rfidinfo",cJSON_CreateString("075583849888190308020911_e280110c20007781e8440985_000000000000000000000000"));
    cJSON_AddItemToObject(my_root,"picType",cJSON_CreateString("src"));
    cJSON_AddItemToObject(my_root,"picdata",cJSON_CreateString("person123"));
    cJSON_AddItemToObject(my_root,"hello",cJSON_CreateString("world"));

    //注冊俩方法
    jrpc_register_procedure(&my_server, say_hello,  "sayHello"  , NULL );
    jrpc_register_procedure(&my_server, mystate_set,"state_set",NULL);
    jrpc_register_procedure(&my_server, mystate_get,"state_get",NULL);
    jrpc_register_procedure(&my_server, exit_server,  "exit"  , NULL );
    jrpc_server_run(&my_server);
    jrpc_server_destroy(&my_server);
    return  0;
}

3.编译测试

在这里插入图片描述

在这里插入图片描述

#!/bin/sh
# @Author: yyh
# @Date:   2023-03-13 14:42:11
# @Last Modified by:   yyh
# @Last Modified time: 2023-03-13 14:53:56

PC_IP=192.168.5.148
MYLIBDIR=/tmp/lib 
MYINCDIR=/tmp/include 
my_eth=eth0.1

# string=`ifconfig $my_eth`
# string=${string#*inet addr:}
# string=${string%%  Bcast*}
# echo $string
# string=192.168.5.241


cd /tmp
chmod 0777 /tmp/*
mkdir $MYLIBDIR -p
mkdir $MYINCDIR -p
if [ $1 = "get_lib" ]
    cd $MYLIBDIR
    tftp -g -r libev.a             $PC_IP
    tftp -g -r libev.la         $PC_IP
    tftp -g -r libev.so         $PC_IP
    tftp -g -r libev.so.4       $PC_IP
    tftp -g -r libev.so.4.0.0   $PC_IP
elif [ $1 = "get_inc" ]
then
    cd $MYINCDIR
    tftp -g -r cJSON.h             $PC_IP
    tftp -g -r jsonrpc-c.h         $PC_IP
    tftp -g -r event.h             $PC_IP
    tftp -g -r ev++.h             $PC_IP
    tftp -g -r ev.h             $PC_IP

elif [ $1 = "get_test" ]
then
    tftp -g -r test     $PC_IP
    chmod 0777 ./*
elif [ $1 = "path_set" ]
then
    export C_INCLUDE_PATH=$C_INCLUDE_PATH:/tmp/include
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tmp/lib
    echo $C_INCLUDE_PATH  
    echo $LD_LIBRARY_PATH
fi
chmod 0777 /tmp/*
测试结果如下

运行./test

PC运行测试脚本

在这里插入图片描述

三、jsonrpc相关概念

JSON-RPC,是一个无状态且轻量级的远程过程调用(RPC)传送协议,其传递内容透过 JSON 为主

请求对象

一个请求对象包含下列成员:
jsonrpc
method
params
id

注意:

params参数结构必须是数组,或者数组对象
例如:

"params":["hello","world"]
"params":[{"hello""world"},{"key":"value"}]

响应对象

jsonrpc
result
error
id

注意:

响应对象必须包含 result 或 error 字段,但两个字段不能同时存在。

错误对象

code
message
data

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yengi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值