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

一、编译环境准备

1.1 开发工具

DevEco-Studio下载。

1.2 SDK下载

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

  • 安装SDK到本地

请添加图片描述

请添加图片描述

请添加图片描述

  • 根据SDK安装位置获取SDK

请添加图片描述

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

请添加图片描述

二、编译鸿蒙架构

​ 第三方库编译鸿蒙架构有两种方式。一种是使用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。文件之间的目录结构如下:

    请添加图片描述

  • 执行脚本

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

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

    请添加图片描述

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

三、使用库文件

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

3.1 创建NAPI工程

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

请添加图片描述

  • 添加二进制文件到工程

请添加图片描述

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

请添加图片描述

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)
    

请添加图片描述

四、编写NAPI接口

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

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

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

4.1 NAPI编写示例

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

请添加图片描述

  • 编写接口

    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.rhkb.cn/news/383943.html

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

相关文章

SSD基本架构与工作原理

SSD的核心由一个或多核心的CPU控制器、DRAM缓存以及多个NAND闪存芯片组成。CPU控制器负责管理所有读写操作,并通过DRAM缓存存储映射表等元数据,以加速寻址过程。 NAND闪存则是数据存储的实际介质,其组织结构从大到小依次为通道(包…

海山数据库(He3DB)性能优化方案解析

前端优化是一个永恒的话题,每个前端开发者都希望自己的页面能够快速加载,给用户良好的体验。但往往事与愿违。因此,本文从编码优化、构建优化、部署优化三方面入手进行web页面性能优化。 1. 编码优化 1.1. Css优化 1.1.1. 合理使用css选择…

HarmonyOS NEXT零基础入门到实战-第四部分

自定义组件: 概念: 由框架直接提供的称为 系统组件, 由开发者定义的称为 自定义组件。 源代码: Component struct MyCom { build() { Column() { Text(我是一个自定义组件) } } } Component struct MyHeader { build() { Row(…

【React】package.json 文件详解

文章目录 一、package.json 文件的基本结构二、package.json 文件的关键字段1. name 和 version2. description3. main4. scripts5. dependencies 和 devDependencies6. repository7. keywords8. author 和 license9. bugs 和 homepage 三、package.json 文件的高级配置1. 配置…

十、SpringBoot 统⼀功能处理【拦截器、统一数据返回格式、统一异常处理】

十、SpringBoot 统⼀功能处理 1. 拦截器【HandlerInterceptor、WebMvcConfig】1.1 拦截器快速⼊⻔⾃定义拦截器:实现HandlerInterceptor接⼝,并重写其所有⽅法注册配置拦截器:实现WebMvcConfigurer接⼝,并重写addInterceptors⽅法…

压测实操--produce压测方案

作者:九月 环境信息: 操作系统centos7.9,kafka版本为hdp集群中的2.0版本。 Producer相关参数 使用Kafka自带的kafka-producer-perf-test.sh脚本进行压测,该脚本参数为: 在producer涉及到性能的关键因素可能会存在如…

DetectorRS

文章目录 AbstractMethodExperimentAblation StudyMain Results Conclusion未来展望 link code Abstract 本文介绍了一种新的对象检测器——DetectoRS,通过在骨干网络设计中引入递归特征金字塔和可切换的空洞卷积机制,实现了出色的性能提升。在宏观层面…

谷粒商城实战笔记-54-商品服务-API-三级分类-拖拽效果

文章目录 一,54-商品服务-API-三级分类-修改-拖拽效果1,el-tree控件加上允许拖拽的属性2,是否允许拖拽3,完整代码 一,54-商品服务-API-三级分类-修改-拖拽效果 本节的主要内容是给三级分类树形结构加上拖拽功能&#…

四、GD32 MCU 常见外设介绍 (4) EXTI 中断介绍

4.EXTI 中断介绍 EXTI(中断/事件控制器)包含多个相互独立的边沿检测电路并且能够向处理器内核产生中断请求或唤醒事件。 EXTI 有三种触发类型:上升沿触发、下降沿触发和任意沿触发。 EXTI中的每一个边沿检测电路都可以独立配置和屏蔽。 4.1.GD32 EXTI 外设原理简介…

如何使用C#自制一个Windows安装包

原文链接:https://www.cnblogs.com/zhaotianff/p/17387496.html 以前都在用InstallShield制作安装包,基本需求是能满足的,但也有一些缺点: 1、界面不能完全定制 2、不能直接调用代码里的功能 平常使用一些其它软件,…

【基础算法总结】优先级队列

优先级队列 1.最后一块石头的重量2.数据流中的第 K 大元素4.前K个高频单词4.数据流的中位数 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃😃 1…

FPGA开发——LED流水灯实现先从左往右流水,再从右往左流水

一、概述 我们在设计完一个方向的流水灯的设计时,总是会想实现让流水灯倒着流水回去的设计,这里我也是一样,实现这种设计的方法有很多种,其中就有直接使用case语句将所有可能包含进去编写,这种设计方法是最简单的&…

leetcode日记(51)不同路径Ⅱ

和上一道题(无障碍物的最短路径)很像,但事实上比上一题多了优化方法 根据上一题改的代码如下,添加了对障碍物的判定,如果有障碍物则将数组值设为0。 class Solution { public:int uniquePathsWithObstacles(vector&l…

Origin制作线性拟合回归图

选中数据,点下方散点图 调整散点颜色 在分析中打开线性拟合回归 添加文本 显示上轴

算法 —— 暴力枚举

目录 循环枚举 P2241 统计方形(数据加强版) P2089 烤鸡 P1618 三连击(升级版) 子集枚举 P1036 [NOIP2002 普及组] 选数 P1157 组合的输出 排列枚举 P1706 全排列问题 P1088 [NOIP2004 普及组] 火星人 循环枚举 顾名思…

keil调试SH79F7416

仿真器JET51A, 调试设置 选择器件 再次点击调试就一切正常啦

快速汇总公司产品涉及的项目(服务、站点)

文章目录 引言I 快速汇总公司产品涉及的项目II 常用工具jar包转成exe应用远程操作常用命令III 把应用做成windows服务在后台运行借助工具`instsrv.exe`和`srvany.exe`把应用做成windows服务的步骤SysWOW64 文件夹的作用引言 需求:汇总 平台涉及站点和服务信息 I 快速汇总公司…

SkyWalking入门搭建【apache-skywalking-apm-10.0.0】

Java学习文档 视频讲解 文章目录 一、准备二、服务启动2-1、Nacos启动2-2、SkyWalking服务端启动2-3、SkyWalking控制台启动2-4、自定义服务接入 SkyWalking 三、常用监控3-1、服务请求通过率3-2、服务请求拓扑图3-3、链路 四、日志配置五、性能剖析六、数据持久化6-1、MySQL持…

MySQL SQL 编程练习

目录 创建表并插入数据 查看表结构 创建触发器 创建INSERT 触发器 创建DELETE 触发器 创建更新触发器 创建存储过程 创建提取emp_new表所有员工姓名和工资的存储过程s1 创建存储过程s2,实现输入员工姓名后返回员工的年龄 创建一个存储过程s3,有2个参数&…

Pytorch使用教学5-视图view与reshape的区别

有同学后台留言问为什么view有时可对张量进行形变操作,有时就会报错?另外它和reshape功能好像一致,有什么区别呢?本文就带你了解PyTorch中视图的概念。 在PyTorch中对张量进行形变操作时,很多同学也会使用view方法&am…