海思3559万能平台搭建:配置文件iniparser的引入

简介: 配置文件iniparser的引入

前言

 功能上的增增补补其实相对容易,而之所以想叫万能平台,最核心的多亏了配置文件的引入。够用和好用也不仅仅是对于使用者,难道对于开发者就不能提升自己的效率吗?

 大佬之所以能成为大佬,想必除了要有过硬的基础实力,更要有站得更高的眼界和经验。一日,在沟通怎么能让各个平台或者目标客户都能方便移植的讨论上,想起了配置文件。之前考虑这个问题还停留在条件编译上,想着总得遇见其他平台再重新定义或者注释完在编译烧写呗,又或者运行时传参,可是那才能有几种模式啊。好像都只是为了升级而升级,意义并不是很大。

 大佬提到,那能不能像用过的一些开源项目一样,用python去加载配置文件呢,里面有每个部分的配置项参数使能等等,非常快捷方便。

 python确实上手快,但是c语言就不能也按照这样的加载方式,将代码整体框架全部写好编译完,根据用户需求调整配置文件做到不重新编译就能直接使用吗?

 Linux下是没有专门的供给C语言使用的配置文件函数的,以前见过xilinx或者海思的项目也是python来加载的,没有现成的葫芦可以照着画瓢现学一点py肯定是一条路,就怕不熟有超出认知外的bug不好改。不过好歹思路有了先拿c硬写一写,最开始的做法就是按照之前rtsp的方法准备造轮子,但偶然间,发现了iniparser开源项目,可以像那些面向对象语言一样,使用ini文件进行参数配置,就可以避免每次有细微的改动或者功能的裁剪都要打开整个SDK加载编译烧写,直接修改配置文件加载就可以了,加载文件,传参这些基本功能封装的也非常简单好上手,瞬间欣喜万分。虽然需要慢慢完善的地方很多,但是好歹有了雏形

iniparser移植

下载

 Iniparser顾名思义,是针对ini文件的解析器,可对init文件进行解析、设置、删除等操作。ini文件则是我们要写的一些系统或软件的配置文件。源码路径如下

 https://github.com/ndevilla/iniparser

 测试可用版本为3.1

修改iniparser库的Makefile

CC      = aarch64-himix100-linux-gcc
AR     = aarch64-himix100-linux-ar

 直接make生成静态库即可

修改海思sample的Makefile

INIPARSER_LIB ?= $(PWD)/../../iniparser-3.1/src
PLATFORM_LIB ?= $(PWD)/../venc
INC_FLAGS += -I$(INIPARSER_LIB)
INC_FLAGS += -I$(PLATFORM_LIB)
SENSOR_LIBS += $(INIPARSER_LIB)/libiniparser.a

基本语法

 Iniparser库的API可以对ini文件(配置文件)进行解析、设置、删除等操作。

 ini文件的最基本组成单元就是key或者叫property,每个key都有一个名称(name)和对应的值(value):

name=value

而许多个Key可以被归类为一组,即section。组名定义要独立一行,并用中括号括起来:

[section]
name=value

 在section声明下的keys都会和该section关联起来。一个section的作用域会在下一个section声明的地方结束,如果没有下一个section的声明,那么该section的结束地方就是该文件末尾。section是不可以嵌套的。

 定位一个key是用section:key来表示的,所以不同section下的key的名称是可以相同的。

 iniparser库处理名称的时候,会统一换成小写,所以section和property的名称命名是大小写无关的。

 注释要以分号开头:

;comment

示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "iniparser.h"
void create_example_ini_file(void);
int  parse_ini_file(char * ini_name);
int main(int argc, char * argv[])
{
    int     status ;
    if (argc<2) {
        create_example_ini_file();
        status = parse_ini_file("example.ini");
    } else {
        status = parse_ini_file(argv[1]);
    }
    return status ;
}
void create_example_ini_file(void)
{
    FILE    *   ini ;
    ini = fopen("example.ini", "w");
    fprintf(ini,
    "#\n"
    "# This is an example of ini file\n"
    "#\n"
    "\n"
    "[Pizza]\n"
    "\n"
    "Ham       = yes ;\n"
    "Mushrooms = TRUE ;\n"
    "Capres    = 0 ;\n"
    "Cheese    = Non ;\n"
    "\n"
    "\n"
    "[Wine]\n"
    "\n"
    "Grape     = Cabernet Sauvignon ;\n"
    "Year      = 1989 ;\n"
    "Country   = Spain ;\n"
    "Alcohol   = 12.5  ;\n"
    "\n");
    fclose(ini);
}
int parse_ini_file(char * ini_name)
{
    dictionary  *   ini ;
    /* Some temporary variables to hold query results */
    int             b ;
    int             i ;
    double          d ;
    char        *   s ;
    ini = iniparser_load(ini_name);
    if (ini==NULL) {
        fprintf(stderr, "cannot parse file: %s\n", ini_name);
        return -1 ;
    }
    iniparser_dump(ini, stderr);
    /* Get pizza attributes */
    printf("Pizza:\n");
    b = iniparser_getboolean(ini, "pizza:ham", -1);
    printf("Ham:       [%d]\n", b);
    b = iniparser_getboolean(ini, "pizza:mushrooms", -1);
    printf("Mushrooms: [%d]\n", b);
    b = iniparser_getboolean(ini, "pizza:capres", -1);
    printf("Capres:    [%d]\n", b);
    b = iniparser_getboolean(ini, "pizza:cheese", -1);
    printf("Cheese:    [%d]\n", b);
    /* Get wine attributes */
    printf("Wine:\n");
    s = iniparser_getstring(ini, "wine:grape", NULL);
    printf("Grape:     [%s]\n", s ? s : "UNDEF");
    i = iniparser_getint(ini, "wine:year", -1);
    printf("Year:      [%d]\n", i);
    s = iniparser_getstring(ini, "wine:country", NULL);
    printf("Country:   [%s]\n", s ? s : "UNDEF");
    d = iniparser_getdouble(ini, "wine:alcohol", -1.0);
    printf("Alcohol:   [%g]\n", d);
    iniparser_freedict(ini);
    return 0 ;
}

 一目了然,还是相对非常简单的

注意

iniparser_getboolean着重提醒一下,单拎出来因为虽然有些情况我们都习惯1是使能0是关闭,但yes/no,true/false,尤其是在没有代码的配置文件里,表现得还是更加直观的,所以看代码就明白在配置文件里我们该怎么填写vlaue了

int iniparser_getboolean(dictionary * d, const char * key, int notfound)
{
    char    *   c ;
    int         ret ;
    c = iniparser_getstring(d, key, INI_INVALID_KEY);
    if (c==INI_INVALID_KEY) return notfound ;
    if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
        ret = 1 ;
    } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
        ret = 0 ;
    } else {
        ret = notfound ;
    }
    return ret;
}



相关文章
|
JavaScript 安全 算法
基于规则评分的密码强度检测算法分析及实现(JavaScript)
用正则表达式做用户密码强度的通过性判定,过于简单粗暴,不但用户体验差,而且用户帐号安全性也差。那么如何准确评价用户密码的强度,保护用户帐号安全呢?本文分析介绍了几种基于规则评分的密码强度检测算法,并给出了相应的演示程序。大家可以根据自己项目安全性需要,做最适合于自己的方案选择。
2668 0
运行项目遇到:该网页无法正常运作,localhost将您重定向的次数过多时的解决方案
运行项目遇到:该网页无法正常运作,localhost将您重定向的次数过多时的解决方案
399 1
R语言错误处理与调试:如何高效调试R代码
【8月更文挑战第28天】调试R代码是一项需要不断练习和提高的技能。通过理解常见的错误类型、使用`traceback()`查看错误路径、逐步执行代码、利用`tryCatch()`捕获和处理错误、设置更严格的警告级别、利用RStudio的调试工具以及编写可复现的示例,你可以更加高效地调试R代码,并快速解决遇到的问题。
|
12月前
|
JSON 缓存 NoSQL
redis序列化数据时,如何包含clsss类型信息?
通过配置 `com.fasterxml.jackson.databind.ObjectMapper` 的 `enableDefaultTyping` 方法,可以使序列化后的 JSON 包含类信息。
141 2
|
存储 安全 Linux
网络请求的高效处理:C++ libmicrohttpd库详解
网络请求的高效处理:C++ libmicrohttpd库详解
|
搜索推荐 算法 C++
蓝桥杯分糖果、最小化战斗力差距、小蓝零花钱
这是一个关于算法问题的集合,包括三个不同的任务: 1. **分糖果**:肖恩有不同种类的糖果要分给学生,目标是使得到糖果字符串的字典序最大且尽量小。给定糖果种类数和一个初始字符串,输出能达到的最小字典序的最大值。 2. **最小化战斗力差距**:小蓝需要将队员分为两组,每组战斗力差距最小。给定队员数量和战斗力值,找出最小的战斗力差距。 3. **小蓝的零花钱**:小蓝要在序列中分割偶数和奇数,每次分割代价是两端元素差的绝对值。目标是在预算内确定最多能进行多少次这样的分割。 每个问题都提供了输入输出示例和相应的C++代码片段来解决这些问题。
|
监控 程序员 开发工具
如何规范Git提交-参考阿里云开发者社区
这篇文章分享了如何规范Git提交,介绍了commit message的格式规范,并通过webhook监控机制来确保代码提交的规范性,从而提高研发效率和代码维护质量。
|
数据库 Python
【译】Celery文档3:在Django中使用Celery
【译】Celery文档3:在Django中使用Celery
168 0
|
Shell Linux 开发者
【Shell 命令集合 文件管理】Linux 补丁文件应用命令 patch命令使用指南
【Shell 命令集合 文件管理】Linux 补丁文件应用命令 patch命令使用指南
287 0
|
API 开发工具 C语言
【嵌入式开源库】EasyLogger的使用, 一款轻量级且高性能的日志库
【嵌入式开源库】EasyLogger的使用, 一款轻量级且高性能的日志库
1479 0