CMakeLists生成动态库.so和静态库.a

一、下载NDK CMake

- NDK :  26.2.11394342  或 23.1.7779620

- CMake : 3.22.1

二、新建android\app\CMakeLists.txt

文件CMakeLists.txt内容

cmake_minimum_required(VERSION 3.4.1)
#mker为项目名称
project('mker')

#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})

#生成动态库.so
add_library(
#c/cpp代码将要编译成为so库的名称,dart代码加载库文件要用这个名称
        native_lib 
        
        SHARED #动态库
#cpp代码文件路径 可以在下面接着随意添加c、c++文件
        cpp/native_lib.cpp )
 
 #生成静态库.a
 add_library(
        #静态库.a的名称
        mystatic

        STATIC #静态库
        #cpp代码文件路径 可以在下面接着随意添加c、c++文件
        cpp/native_lib.cpp )
 

三、app/build.gradle配置

    defaultConfig {
。。。。。。
//新增
        externalNativeBuild {
            cmake {
                targets 'mystatic','native_lib'
            }
// > [CXX1201] ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].
//            ndk {
//                abiFilters 'x86_64','x86','arm64-v8a', 'armeabi-v7a'
//            }
        }

    }

 //新增:编译自己的CMake进项目
    externalNativeBuild {
        // Encapsulates your CMake build configurations.
        cmake {
            path "../CMakeLists.txt"
        }
    }
    

四、放c++代码:/android/app/cpp/native_lib.cpp

#include <stdint.h>
#include <cstring>
extern "C" {
__attribute__((visibility("default"))) __attribute__((used))
int32_t native_add(int32_t x, int32_t y) {
    return x + y;
}
__attribute__((visibility("default"))) __attribute__((used))
int32_t native_add2(int32_t x, int32_t y) {
    return x + y;
}
__attribute__((visibility("default"))) __attribute__((used))
char* concat(const char* str1, const char* str2) {
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    char* result = new char[len1 + len2 + 1];
    strcpy(result, str1);
    strcat(result, str2);
    return result;
}
}


extern "C" __attribute__((visibility("default"))) __attribute__((used))
int32_t native_add3(int32_t x, int32_t y) {
    return x + y;
}

五、生成动态库.so和静态库.a

项目根目录下执行命令:flutter build apk后app文件夹下会自动生成libs文件夹,里面放的是不同cpu下的.so文件

.a存放的位置:android/app/.cxx/RelWithDebInfo/5p5v2i3r/arm64-v8a/libmystatic.a

注:生成的.a文件好像不能使用,通过命令行lipo -info xxx.a 查不出cpu架构类型

六、动态库.so验证:

1.pubspec.yaml文件下添加依赖 ffi: ^2.1.2
2.项目lib文件夹下放native_add.dart
import 'dart:ffi' as ffi;
import 'dart:ffi';
import 'dart:io'; // For Platform.isX

import 'package:ffi/ffi.dart';

final DynamicLibrary nativeAddLib = Platform.isAndroid
    ? DynamicLibrary.open("libnative_lib.so")
    : DynamicLibrary.process();

final int Function(int x, int y) nativeAdd = nativeAddLib
    .lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add")
    .asFunction();

final int Function(int x, int y) nativeAdd2 = nativeAddLib
    .lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add2")
    .asFunction();

final int Function(int x, int y) nativeAdd3 = nativeAddLib
    .lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add3")
    .asFunction();

typedef A2 = Pointer<Utf8> Function(ffi.Pointer<Utf8>, ffi.Pointer<Utf8>);

String concatStr(String str1, String str2) {
  final privateKeyPtr = str1.toNativeUtf8();
  final hexCidMessagePtr = str2.toNativeUtf8();
  final concat =
      nativeAddLib.lookup<ffi.NativeFunction<A2>>('concat').asFunction<A2>();
  return concat(privateKeyPtr, hexCidMessagePtr).toDartString();
}

bool isExistSymbol(String symbol) {
  final isOk = nativeAddLib.providesSymbol(symbol);
  return isOk;
}


3.flutter调用.so里的方法
 int result = nativeAdd(1, 2);
    int result2 = nativeAdd2(1, 2);
    int result3 = nativeAdd3(1, 2);
    print(
        '-------------------------result:$result---result2:$result2---result3:$result3');

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Visual Basic6.0零基础教学(4)—编码基础,数据类型与变量

编码基础,数据类型与变量 文章目录 编码基础,数据类型与变量前言一、VB中的编程基础二、VB的基本字符集和词汇集1、字符集2、词汇集 VB中的数据类型VB中的变量与常量一.变量和常量的命名规则二.变量声明1.用Dim语句显式声明变量三. 常量 运算符和表达式一. 运算符 1. 算术运算符…

promethus的安装使用

1、# 软件下载地址 https://prometheus.io/download/ https://grafana.com/grafana/download https://prometheus.io/download/ Prometheus是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的。 Prometheus 的优点 1、非常少的外部依赖,安装…

解决sqlalchemy执行语句提示Not an executable object

问题&#xff1a; from sqlalchemy import create_engine# 数据库的变量 HOST 127.0.0.1 PORT 3306 DATA_BASE itbz USERroot PWD123456 # DB_URL f数据库的名驱动名://{USER}:{PWD}{HOST}:{PORT}/{DATA_BASE} DB_URL fmysqlpymysql://{USER}:{PWD}{HOST}:{PORT}/{DATA_B…

定时器 c++ 基于时间线

获取当前时间std::chrono::system_clock::now(); std::chrono::time_point_cast<std::chrono::milliseconds>(now) 是 std::chrono 标准库中的一个函数调用&#xff0c;用于将时间点 now 转换为毫秒级别精度的时间点。 friend class timermanger; 表示将类 timermanger …

24年3月下半笔记(个人向)(更新中)

3.19 开始复工复产了 发现poe网站上可以免费用chatgpt&#xff0c;用了两天就彻底产生依赖性了 继续看d2l&#xff0c;之前看到第三章结束&#xff0c;今天从4.1看到4.6 第四章讲mlp&#xff0c;老生常谈&#xff0c;各种激活函数ReLU、sigmoid、tanh 然后是防止过拟合&am…

Verilog刷题笔记43

题目&#xff1a;Exams/m2014 q4b 解题&#xff1a; module top_module (input clk,input d, input ar, // asynchronous resetoutput q);always(posedge clk,posedge ar)beginif(ar1)q<0;elseq<d;endendmodule结果正确&#xff1a; 补充&#xff1a; 同步复位和异步…

Jenkins+Ant+Jmeter接口自动化集成测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、Jenkins安装配置 1、安装配置JDK1.6环境变量&#xff1b; …

抓取京东/淘宝类数据#Javascript#商品详情图片

提出问题 如何在京东商城爬取出各个商品的相关信息(价格、名称、评价、店铺名等等)&#xff0c;比如&#xff0c;打开web京东网站&#xff0c;那么商品展示列表的所有商品的信息&#xff0c;怎么爬下来&#xff0c;怎么保存到表格中&#xff1f; 我们来看看怎么实现这个功能。…

手写springboot启动器, 学习SpringBoot的最佳实践

自己手写的SpringBoot启动器, 是一个学习了解SpringBoot启动逻辑和了解springboot原理的不错的实践Demo. 废话不多说,直接上代码: 项目结构 maven多项目结构, myspringboot 自己手写的SpringBoot启动器 service-demo 用来测试SpringBoot启动器的示例项目 项目pom依赖 1.…

Istio 部署 Spring Coud 微服务应用

Istio 服务部署 这篇文章讲述如何将 Java Spring Cloud 微服务应用部署到 Istio mesh 中。 准备基础环境 使用 Kind 模拟 kubernetes 环境。文章参考&#xff1a;https://blog.csdn.net/qq_52397471/article/details/135715485 在 kubernetes cluster 中安装 Istio 创建一…

接口用例之好用例和坏用例

自动化测试的重要性显而易见&#xff0c;但自动化测试又无法解决所有问题&#xff0c;所以说完全依赖自动化是不可能的&#xff0c;但完全没有自动化是万万不能。在软件开发项目中&#xff0c;重度依赖人力进行持续回归是一件非常枯燥的重复工作。企业需要花费大量的时间和金钱…

代码随想录算法训练营第33天|1005.K次取反后最大化的数组和|134. 加油站|135. 分发糖果

代码随想录算法训练营第33天|1005.K次取反后最大化的数组和|134. 加油站|135. 分发糖果 1005.K次取反后最大化的数组和 本题简单一些&#xff0c;估计大家不用想着贪心 &#xff0c;用自己直觉也会有思路。 https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%…

【QA】MySQL导出某数据库的所有数据为sql文件,包含建库命令、建表命令。

文章目录 前言Windows系统下 | mysqldump导出数据库数据Docker中导入初始化数据【补充】通过命令行&#xff0c;执行sql文件&#xff0c;将数据导入到数据库在MySQL外面执行在MySQL中执行 前言 我们在用docker部署mysql项目的时候&#xff0c;往往需要对数据库进行数据初始化。…

PLC_博图系列☞RS:复位/置位触发器

PLC_博图系列☞RS&#xff1a;复位/置位触发器 文章目录 PLC_博图系列☞RS&#xff1a;复位/置位触发器背景介绍RS&#xff1a;复位/置位触发器说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 RS 背景介绍 这是一篇关于PLC编程的文章&#xff0c;特别…

蓝桥杯java---螺旋矩阵

解题思路&#xff1a; int [][] arr new int[n][m];int i 0, j -1, temp 1;while (n * m > 0){for (int p 0; p < m; p)//从左自右arr[i][jj1] temp;n--;if (n * m 0) break;for (int p 0; p < n; p)//从上自下arr[ii1][j] temp;m--;if (n * m 0) break;fo…

使用HiBurn烧录鸿蒙.bin文件到Hi3861开发板

鸿蒙官方文档的“Hi3861开发板第一个示例程序”中描述了——如何使用DevEco Device Tool工具烧录二进制文件到Hi3861开发板&#xff1b; 本文将介绍如何使用HiBurn工具烧录鸿蒙的.bin文件到Hi3861开发板。 获取HiBurn工具 通过鸿蒙官方文档我们知道DevEco Device Tool是一个V…

C语言:自定义类型:联合体和枚举

目录 联合体 联合体是什么&#xff1f; 联合体的大小计算 枚举 枚举是什么&#xff1f; 为什么要使用枚举&#xff1f; 联合体 联合体是什么&#xff1f; 联合体也是个自定义类型&#xff0c;它和结构体类似&#xff0c;都是由多个成员构成&#xff0c;可以有不同的内置…

【Java八股面试系列】中间件-Redis

目录 Redis 什么是Redis Redis解决了什么问题 Redis的实现原理 数据结构 String 常用命令 应用场景 List(列表) 常用命令 应用场景 Hash(哈希) 常用命令 应用场景 set(集合) 常见命令​编辑 应用场景 Sorted Set(有序集合) 常见命令​编辑 应用场景 数据持…

【数据结构】线性表的定义与基本操作

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

【搭建私人图床】本地PHP搭建简单Imagewheel云图床,在外远程访问

目录 ⛳️推荐 1.前言 2. Imagewheel网站搭建 2.1. Imagewheel下载和安装 2.2. Imagewheel网页测试 2.3.cpolar的安装和注册 3.本地网页发布 3.1.Cpolar临时数据隧道 3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09; 3.3.Cpolar稳定隧道&#xff08;本地设置&…