GMSSL2.x编译鸿蒙静态库和动态库及使用

news/2024/9/19 13:01:48/文章来源:https://www.cnblogs.com/yujiabo/p/18316450

一、编译环境准备

1.1 开发工具

DevEco-Studio下载。

1.2 SDK下载

​ 下载编译第三方库的SDK有两种方式,第一种方式从官方渠道根据电脑系统选择对应的SDK版本,第二种方式通过DevEco-Studio下载SDK。本文只介绍通过DevEco-Studio下载SDK的方式。

  • 安装SDK到本地

Xnip2024-07-22_09-55-12

Xnip2024-07-22_10-13-51 Xnip2024-07-22_10-25-15
  • 根据SDK安装位置获取SDK

Xnip2024-07-22_10-38-51

  • 将SDK复制到GMSSL的同级目录并更名为ohos-sdk

Xnip2024-07-22_16-36-50

二、编译鸿蒙架构

​ 第三方库编译鸿蒙架构有两种方式。一种是使用C/C++原生构建工具configure、makefile编译,一种是使用lycium框架快速交叉编译。本文只详细介绍通过configure、makefile编译的方式。

2.1 原生工具构建

  • 编写编译脚本

    #!/bin/bash# Define paths and environment variables
    # 获取脚本当前所在路径
    CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    # 获取GmSSL源码路径
    GMSSL_DIR=$CURRENT_PATH/GmSSL2.5.4
    # 取脚本执行的第一个参数
    OHOS_TARGET_ABI=$1
    # 获取鸿蒙SDK路径
    export OHOS_SDK=$CURRENT_PATH/ohos-sdk# 编译64位架构
    if [ "$OHOS_TARGET_ABI" == "arm64-v8a" ]
    thenexport AS=${OHOS_SDK}/native/llvm/bin/llvm-asexport CC=${OHOS_SDK}/native/llvm/bin/aarch64-unknown-linux-ohos-clangexport CXX=${OHOS_SDK}/native/llvm/bin/aarch64-unknown-linux-ohos-clang++export LD=${OHOS_SDK}/native/llvm/bin/ld.lldexport STRIP=${OHOS_SDK}/native/llvm/bin/llvm-stripexport RANLIB=${OHOS_SDK}/native/llvm/bin/llvm-ranlibexport OBJDUMP=${OHOS_SDK}/native/llvm/bin/llvm-objdumpexport OBJCOPY=${OHOS_SDK}/native/llvm/bin/llvm-objcopyexport NM=${OHOS_SDK}/native/llvm/bin/llvm-nmexport AR=${OHOS_SDK}/native/llvm/bin/llvm-arexport CFLAGS="-DOHOS_NDK -fPIC -D__MUSL__=1"export CXXFLAGS="-DOHOS_NDK -fPIC -D__MUSL__=1"outdir=arm64-v8acd ${GMSSL_DIR}./Configure linux-aarch64elif [ "$OHOS_TARGET_ABI" == "armeabi-v7a" ]
    then
    #编译32位架构export AS=${OHOS_SDK}/native/llvm/bin/llvm-asexport CC=${OHOS_SDK}/native/llvm/bin/armv7-unknown-linux-ohos-clangexport CXX=${OHOS_SDK}/native/llvm/bin/armv7-unknown-linux-ohos-clang++export LD=${OHOS_SDK}/native/llvm/bin/ld.lldexport STRIP=${OHOS_SDK}/native/llvm/bin/llvm-stripexport RANLIB=${OHOS_SDK}/native/llvm/bin/llvm-ranlibexport OBJDUMP=${OHOS_SDK}/native/llvm/bin/llvm-objdumpexport OBJCOPY=${OHOS_SDK}/native/llvm/bin/llvm-objcopyexport NM=${OHOS_SDK}/native/llvm/bin/llvm-nmexport AR=${OHOS_SDK}/native/llvm/bin/llvm-arexport CFLAGS="-DOHOS_NDK -fPIC -D__MUSL__=1"export CXXFLAGS="-DOHOS_NDK -fPIC -D__MUSL__=1"outdir=armeabi-v7acd ${GMSSL_DIR}./Configure linux-generic32elif [ "$OHOS_TARGET_ABI" == "x86_64" ]
    then
    #编译32位架构export AS=${OHOS_SDK}/native/llvm/bin/llvm-asexport CC=${OHOS_SDK}/native/llvm/bin/x86_64-unknown-linux-ohos-clangexport CXX=${OHOS_SDK}/native/llvm/bin/x86_64-unknown-linux-ohos-clang++export LD=${OHOS_SDK}/native/llvm/bin/ld.lldexport STRIP=${OHOS_SDK}/native/llvm/bin/llvm-stripexport RANLIB=${OHOS_SDK}/native/llvm/bin/llvm-ranlibexport OBJDUMP=${OHOS_SDK}/native/llvm/bin/llvm-objdumpexport OBJCOPY=${OHOS_SDK}/native/llvm/bin/llvm-objcopyexport NM=${OHOS_SDK}/native/llvm/bin/llvm-nmexport AR=${OHOS_SDK}/native/llvm/bin/llvm-arexport CFLAGS="-DOHOS_NDK -fPIC -D__MUSL__=1"export CXXFLAGS="-DOHOS_NDK -fPIC -D__MUSL__=1"outdir=x86_64# Navigate to OpenSSL directory./Configure linux-x86_64elseecho "Unsupported target ABI: $ANDROID_TARGET_ABI"exit 1
    fimake# Copy the outputs
    OUTPUT_INCLUDE=$CURRENT_PATH/ohos_libs/include
    OUTPUT_LIB=$CURRENT_PATH/ohos_libs/lib/${outdir}
    mkdir -p $OUTPUT_INCLUDE
    mkdir -p $OUTPUT_LIB
    cp -RL include/openssl $OUTPUT_INCLUDE
    cp libcrypto.so.1.1 $OUTPUT_LIB
    cp libcrypto.a $OUTPUT_LIB
    cp libssl.so.1.1 $OUTPUT_LIB
    cp libssl.a $OUTPUT_LIB
    

    将编写好的脚本文件命名为ohos.sh。文件之间的目录结构如下:

    Xnip2024-07-22_11-23-56

  • 执行脚本

    cd到HarmonyOS-SDK目录下,依次执行如下命令,分别编译64位、32位、x86_64的鸿蒙架构。

    ohos.sh  arm64-v8a
    
    ohos.sh  armeabi-v7a
    
    ohos.sh  x86_64
    
  • 编译问题

    截屏2024-07-19 11.11.09

    解决方案:删除GMSSL2.5.4源码中对getcontext、makecontext、setcontext等函数的引用。

2.2 使用lycium框架编译

  • 环境配置

    查看环境配置文档

  • 编译步骤

    查看lycium编译步骤

三、使用库文件

​ 鸿蒙工程可以使用.a的静态库和.so的动态库,两种类型的库引用一种即可。

3.1 创建NAPI工程

​ NAPI是OpenHarmony系统中的原生模块扩展开发框架,提供JavaScript与C/C++模块之间相互调用的交互能力。

Xnip2024-07-22_14-43-42

  • 添加二进制文件到工程

Xnip2024-07-22_15-03-28

如果该三方库二进制文件为so文件,还需要将so文件拷贝到工程目录的entry/libs/${OHOS_ARCH}/目录下,如下图:

so_location

3.2 配置链接

​ 添加二进制文件后需要在cpp目录的CMakeLists.txt文件中添加对应target_link_libraries才能被工程引用。

  • 配置静态库链接

    target_link_libraries(product PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gmssl/${OHOS_ARCH}/lib/libcrypto.a)
    target_link_libraries(product PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gmssl/${OHOS_ARCH}/lib/libssl.a)
    
  • 配置动态库链接

    target_link_libraries(product PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gmssl/${OHOS_ARCH}/lib/libcrypto.so)
    target_link_libraries(product PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gmssl/${OHOS_ARCH}/lib/libssl.so)
    
  • 配置头文件

    target_include_directories(product PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gmssl/${OHOS_ARCH}/include)
    

Xnip2024-07-22_15-16-13

四、编写NAPI接口

​ 配置完三方库的链接和头文件路径后,可以根据各自的业务逻辑调用三方库对应的接口完成NAPI接口的编写,NAPI接口开发可以参照以下文档学习。

  1. 使用Node-API实现跨语言交互开发流程

  2. C/C++三方库使用

4.1 NAPI编写示例

​ NAPI接口编写的基本思路是将从JavaScript层传入的参数转成C/C++数据类型,然后调用第三方库接口执行业务逻辑,最后将执行的结果转成JavaScript数据类型返回给JavaScript层。

Xnip2024-07-22_15-43-46

  • 编写接口

    napi_init.cpp文件中编写NAPI接口。

第一步:获取JS层传入的参数转成C/C++数据类型并将转换的结果作为参数传入第三方库函数中。

static napi_value gm_post(napi_env env, napi_callback_info info){size_t argc = 4;napi_value args[4];// 获取JS参数napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);char url[512] = {0},parameter[MAX_BUF] = {0}, filePath[1024] = {0};size_t url_len,parameter_len,filePath_len;double timeOut;// 获取请求地址 napi(JS)数据类型转c/c++数据类型napi_get_value_string_utf8(env, args[0], url, sizeof(url), &url_len);// 获取请求参数 napi(JS)数据类型转c/c++数据类型napi_get_value_string_utf8(env, args[1], parameter, sizeof(parameter), &parameter_len);// 获取超时时间napi_get_value_double(env, args[2], &timeOut);// 获取证书路径napi_get_value_string_utf8(env, args[3], filePath, sizeof(filePath), &filePath_len);// 调用gmssl库的post请求方法resp_t *resp = infosecPost(url, parameter, timeOut, NULL, filePath);// 格式转换后返回响应数据return transformRespToNapi(env, resp);
}

第二步:将第三方库返回的结果转成JavaScript数据类型

static napi_value transformRespToNapi(napi_env env,resp_t *resp){napi_value res_obj;// 1.创建对象napi_status status = napi_create_object(env, &res_obj);if (status != napi_ok) {napi_throw_error(env,"-1","创建响应数据对象异常");return nullptr;}// 2.创建data属性值napi_value res_data;status = napi_create_string_utf8(env, resp->data, NAPI_AUTO_LENGTH, &res_data);if (status != napi_ok) {napi_throw_error(env,"-2","创建属性值异常");return nullptr;}status = napi_set_named_property(env, res_obj, "data", res_data);if (status != napi_ok) {napi_throw_error(env,"-3","设置对象的属性异常");return nullptr;}// 3.创建code属性napi_value res_code;status = napi_create_double(env, resp->code, &res_code);if (status != napi_ok) {napi_throw_error(env,"-2","创建属性值异常");return nullptr;}status = napi_set_named_property(env, res_obj, "code", res_code);if (status != napi_ok) {napi_throw_error(env,"-3","设置对象的属性异常");return nullptr;}resp_free(resp);return res_obj;
}

第三步:ArkTS接口与C/C++接口绑定和映射

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{napi_property_descriptor desc[] = {{ "send_gm_post", nullptr, gm_post, nullptr, nullptr, nullptr, napi_default, nullptr }};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;
}
EXTERN_C_END

​ 说明:send_gm_post是ArkTS的函数名,gm_post是C/C++函数名。

  • 声明ArkTS侧的方法

Index.d.ts文件中声明ArkTS侧的方法。

export const send_gm_post: (url: string,parameters:string,timeOut:number,caPath:string) => object;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/758823.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义测试器

测试器测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,使用”is”关键字来进行测试。{% set name=ab %} {% if name is lower %} <h2>"{{ name }}" are all lower case.</h2> {% endif %}测试器本质上也是一个函数,它的第一个参数就是待…

Invalid or unexpected token

异常:原因: js代码中可能符号错误,如括号没有关闭、半角全角、 本次的原因是双引号没有关闭

minix 文件系统

来自:https://in1t.top/2020/05/04/minix-1-0-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/ 下一个模块将是 fs(file system) 文件系统模块,在开始阅读源码之前,先对 Linux 0.11 中使用的 Minix 1.0 文件系统有个大致的概念,这对之后的代码阅读会有很大的帮助 文件系统是操作系统…

栅格地图

在ROS中,地图是非常基本的元素,特别对于2D激光SLAM而言,栅格地图可以说是必不可少的元素。机器人在需要前往目标点时,需要在栅格地图中找到一条合适的路径从当前点到达目标点,这部分内容在move_base中有了详细的接口,可以直接调用并返回路径。但是作为一名工程师,不仅要…

VA02/VA03增加alv

项目背景:搞备库单(新建一种类型的销售订单),备库单不出货(通过排程明细类别控制,也需要新增),正式销售订单创建时,备库单分配数量给正式SO,SO的排程明细类别也是新增的(不跑MRP), 创建后,如果备库单已有库存,则从备库单直接自动调拨库存到正式SO上,还有其它的一…

Folding Strip

第一次在考场中做出来的E题,rank也是来到了20,纪念一下,一定要相信自己呀 构造方法见官方题解,证明见下: 对于原始串\(s\),如果第一个(从左往右数)相同交界不折,选择折后面的交界,那么根据决策包容性,我们可以折一下第一个相同交界,答案不会更差,如下 如果不折第一…

【matplotlib】生成各种图表

一、场景工作中,可能需要使用脚本分析各种数据,并生成图表二、工具matplotlibhttps://matplotlib.org/stable/install/index.html三、安装python -m pip install -U pip python -m pip install -U matplotlib 四、生成图表 1、折线图import matplotlib.pyplot as plt# 准备数…

浅谈cookie和session

最近写了好多次登录注册的业务接口,那不免会听到session、cookie等概念。那么他们是什么呢?之间的关系?有啥作用呢?我这次终于好好捋清楚他们的关系了,这次做一次学习总结。关于用户信息存储相关的问题 背景 先讨论Session和Cookie,我们先了解其诞生的背景,毕竟需求推动…

施工行业必备:2024年值得选择的项目管理工具

国内外主流的10款施工项目进度管理软件对比:PingCode、Worktile、Contractor Foreman、建设工程项目管理平台(JSGC)、智慧工地综合管理系统、工程项目信息管理系统(GCXX)、Buildertrend、Procore、Autodesk Construction Cloud、Fieldwire、ClickUp、monday.com。在施工行…

spingboot 发布 https

1 进入jdk安装目录,我的是在C:\Program Files\Java\jdk1.8.0_311\bin 菜单栏 输入 cmd回车 2. 使用JDK自带的keytool工具生成ssl证书(这里注意JDK版本,版本向上兼容,高版本生成的密钥,不能用于低版本) keytool -genkey -alias gateway -storetype PKCS12 -keyalg RSA -ke…

thinkPHP/fastAdmin框架使用memcached缓存

1.安装memcached扩展: 2.重启PHP,在thinkPHP或者fastAdmin启用扩展(开放相应端口:例如11211) 在fastAdmin中,则需修改config.php里面的cache配置: 3.实际运行测试: 第一个信息正常显示说明运行成功,第二个显示false,说明缓存删除成功每天进步一点点