【华为云技术分享】【玩转Atlas200DK系列】应用开发之 交叉编译第三方库并在工程中使用(jsoncpp)
在本案中,我们以jsoncpp为例来介绍如何交叉编译第三方库,并在工程中是使用;
1. 从github上下载jsoncpp源码
wget https://github.com/open-source-parsers/jsoncpp/archive/master.zip;
2. 配置源码的交叉编编译环境。在我们安装了DDK的服务器上,arm的编译器在/usr/bin目录下,所以我们在jsoncpp目录下的CMakelist.txt中添加:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER "/usr/bin/aarch64-linux-gnu-gcc")
SET(CMAKE_CXX_COMPILER "/usr/bin/aarch64-linux-gnu-g++")
SET(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu/)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
3. 在源码目录下执行下述命令,即可编译得到arm的libjsoncpp.so
cd jsoncpp-master
mkdir -p ./build/debug
cd ./build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_INCLUDEDIR=include/jsoncpp -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
sudo make && make install
这里的编译到jsoncpp自带的测试用例时报错找不到ld-arrch64-linux.so,不用理会,直接到build/debug/src/lib_json下取编译成功的libjsoncpp就可以了
接下类打开MindStudio,创建一个工程,例如命名为jsoncppTest。
4. 在工程目录下创建lib/host目录,并且就将生成的so拷贝到该目录下;
(本案例中工程基于上一讲的HelloWorld工程,只是将工程文件夹名称改为jsoncppTest,有些图片跟你的工程对不上时没有关系的)
5. 如下图在src/CMakeLists.txt文件中加入如下内容,第一处为jsoncpp添加include目录,include路径在你之前下载的源码中有,第二处添加jsoncpp库的路径,一定要放在../lib/下,该路径会被MindStudio在运行工程师时随out目录一起同步到远端(开发板测);第三处设置链接的库名称。
6. 在graph.config中添加如下内容:
7. 这样准备工作就做完了,可以在工程中使用jsoncpp库了。
首先在Custom.h中添加json头文件:
#include "json/json.h"
并且定义一个变量root_, 用来保存读取json文件的内容;
例如:
/**
* @file Custom.h
*
* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef CUSTOM_ENGINE_H_
#define CUSTOM_ENGINE_H_
#include <iostream>
#include <string>
#include <dirent.h>
#include <memory>
#include <unistd.h>
#include <vector>
#include <stdint.h>
#include "hiaiengine/engine.h"
#include "hiaiengine/multitype_queue.h"
#include "json/json.h"
#define INPUT_SIZE 1
#define OUTPUT_SIZE 1
using hiai::Engine;
using namespace std;
using namespace hiai;
class Custom : public Engine {
public:
Custom() :
inputQueue(INPUT_SIZE) {}
HIAI_StatusT Init(const hiai::AIConfig& config, const std::vector<hiai::AIModelDescription>& modelDesc);
/**
* @ingroup hiaiengine
* @brief HIAI_DEFINE_PROCESS : reload Engine Process
* @[in]: define the number of input and output
*/
HIAI_DEFINE_PROCESS(INPUT_SIZE, OUTPUT_SIZE)
private:
// Private implementation a member variable, which is used to cache the input queue
hiai::MultiTypeQueue inputQueue;
// add a json Value for store the json content.
Json::Value root_;
};
#endif // CUSTOM_ENGINE_H_
8. 在Custom.cpp中调用jsoncpp进行json内容读取
一般情况下,我们将读取配置文件类的操作放在Init函数中操作,在引擎初始化的时候一次操作,后面多次推理均可使用;
注意:labels.json已经被放在./run/out/目录下,该文件会在应用运行时被MindStudio自动同步到远端(开发板测)。
见如下源码,红色部分为新增:
/**
* @file Custom.cpp
*
* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <memory>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include "Custom.h"
#include "hiaiengine/log.h"
#include "hiaiengine/data_type_reg.h"
/**
* @ingroup hiaiengine
* @brief HIAI_DEFINE_PROCESS : implemention of the engine
* @[in]: engine name and the number of input
*/
HIAI_StatusT Custom::Init(const hiai::AIConfig &config,
const std::vector<hiai::AIModelDescription> &modelDesc)
{
//TODO:
// according to the index, choose the class from ables.json.
Json::Reader reader;
std::ifstream ifs("labels.json");//open file
if(!reader.parse(ifs, root_)){
// fail to parse
cout << "parse labels json file failed. file=" << "./labels.json";
}
else{
// print one label for testing.
std::cout<<root_["1"].asString()<<endl;
cout << "parse labels json file successfully.";
}
return HIAI_OK;
}
HIAI_IMPL_ENGINE_PROCESS("Custom", Custom, INPUT_SIZE)
{
//TODO:
//user code here
auto a = std::static_pointer_cast<string>(arg0);
printf("%s\n", (*a).c_str());
//send data
std::shared_ptr<std::string> resultData(new std::string);
*resultData = "over!";
HIAI_StatusT ret = SendData(0, "string", std::static_pointer_cast<void>(resultData));
return ret;
}
9. 编译/运行;在此不赘述;在这里可以看到运行成功,但是并不能看到运行结果的打印,那是因为程序运行在开发板侧,无法看到打印界面,接下来登陆到开发板去运行并查看运行结果。
10. ssh登陆到开发板,可以发现该有的都已经存在了;
11. 直接运行,已经读取到了数据。
end.
作者:山人