基于kotlin native的C与kotlin互相调用

本文测试环境为ubuntu,没有使用IDE;从基本层面了解kotlin native环境中,C和kotlin的编译,互相调用。

1. kotlin 动态库

1.1 动态库编译

源码文件libktest.kt:

//file name:libktest.kt
@OptIn(kotlin.experimental.ExperimentalNativeApi::class)
@CName("testk")  // 指定 C 函数名
fun testk() {println("Hello, Kotlin!")  // 打印并换行
}

执行如下命令: 

kotlinc-native libktest.kt -produce dynamic -o libktest
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ cat libktest.kt @OptIn(kotlin.experimental.ExperimentalNativeApi::class)
@CName("testk")  // 指定 C 函数名
fun testk() {println("Hello, Kotlin!")  // 打印并换行
}
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ cat build.sh 
#!/bin/bashkotlinc-native libktest.kt -produce dynamic -o libktest#执行shell命令
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ./build.sh #获取的结果
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 888
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ 

执行shell脚步后获取libktest_api.h和libktest.so,so文件是linux平台可以直接link的调用的的动态库,h文件是生成的头文件

与c代码编译的动态库比较,kotlin的动态库文件比C代码编译的动态库文件大很多,so文件除了包含testk函数外,还额外包含了很多其他信息。看起来是kotlin相关的一些信息,暂时还未研究这些信息,应该是kotlinc-native编译native动态库时做的特别处理。因此看来在客户端瘦身时,这里为考虑点。

1.2 kotlin so文件的动态链接调用

1.2.1 kotlin 代码的动态链接

main.kt主程序代码

import ktest.*           // 导入生成的绑定
import kotlinx.cinterop.*@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
fun main() {testk()//println("3 + 5 = ${add(3, 5)}")          // 调用 C 函数//println("sqrt(9.0) = ${sqrtf(9.0f)}")    // 注意类型匹配(Float)
}

 创建ktest.def文件,描述需要绑定(binding)的内容, kotlin代码调用native模块的前提条件

headers = libktest_api.h
headerFilter = libktest_api.h
package = ktestcompilerOpts.linux = -I.
linkerOpts.linux = -L./ -lktest

 关于def文件的配置可以参考:

定义文件 | Kotlin 语言参考文档 中文版

 执行如下命令生成绑定:

cinterop  -def ktest.def -o ktest.klib

结果如下:

liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 892
-rw-r--r-- 1 liucx liucx    129 4月   2 15:35 ktest.def
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ cinterop  -def ktest.def -o ktest.klib
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 904
-rw-r--r-- 1 liucx liucx   7694 4月   2 15:35 ktest.klib
drwxr-xr-x 3 liucx liucx   4096 4月   2 15:35 ktest.klib-build
-rw-r--r-- 1 liucx liucx    129 4月   2 15:35 ktest.def
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ 

生成ktest.klib 和ktest.klib-build.

编译main.kt,获取maink程序,终端输出信息如下:

liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 908
-rw-r--r-- 1 liucx liucx    305 4月   2 15:37 main.kt
-rw-r--r-- 1 liucx liucx   7694 4月   2 15:35 ktest.klib
drwxr-xr-x 3 liucx liucx   4096 4月   2 15:35 ktest.klib-build
-rw-r--r-- 1 liucx liucx    129 4月   2 15:35 ktest.def
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ kotlinc-native main.kt -library ktest.klib  -o maink
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 1384
-rwxr-xr-x 1 liucx liucx 485224 4月   2 15:37 maink.kexe
-rw-r--r-- 1 liucx liucx    305 4月   2 15:37 main.kt
-rw-r--r-- 1 liucx liucx   7694 4月   2 15:35 ktest.klib
drwxr-xr-x 3 liucx liucx   4096 4月   2 15:35 ktest.klib-build
-rw-r--r-- 1 liucx liucx    129 4月   2 15:35 ktest.def
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt

 查看执行结果:

liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ./maink.kexe 
Hello, Kotlin!

 ps:动态库的路径需要手动临时配置下。

至此完成了kotlin调用native动态库的测试。

需要进一步研究的点:

  1. def文件的binding操作具体做了什么,生成文件的作用
  2. kotlin native编译的native可执行程序变大了,那么kotlin的编译过程中注入信息以及这写注入的作用
  3. OptIn的注解作用原理和过程

1.2.2 C 代码的动态链接

liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ cat main.c #include "libktest_api.h"
void main() {testk();
}
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 1388
-rw-r--r-- 1 liucx liucx     56 4月   2 15:48 main.c
-rwxr-xr-x 1 liucx liucx 485224 4月   2 15:37 maink.kexe
-rw-r--r-- 1 liucx liucx    305 4月   2 15:37 main.kt
-rw-r--r-- 1 liucx liucx   7694 4月   2 15:35 ktest.klib
drwxr-xr-x 3 liucx liucx   4096 4月   2 15:35 ktest.klib-build
-rw-r--r-- 1 liucx liucx    129 4月   2 15:35 ktest.def
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ gcc main.c -o cmain.exe -L. -lktest -Wl,-rpath=./
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ls -lt
总用量 1400
-rwxr-xr-x 1 liucx liucx   8288 4月   2 15:48 cmain.exe
-rw-r--r-- 1 liucx liucx     56 4月   2 15:48 main.c
-rwxr-xr-x 1 liucx liucx 485224 4月   2 15:37 maink.kexe
-rw-r--r-- 1 liucx liucx    305 4月   2 15:37 main.kt
-rw-r--r-- 1 liucx liucx   7694 4月   2 15:35 ktest.klib
drwxr-xr-x 3 liucx liucx   4096 4月   2 15:35 ktest.klib-build
-rw-r--r-- 1 liucx liucx    129 4月   2 15:35 ktest.def
-rwxr-xr-x 1 liucx liucx 892544 4月   2 15:14 libktest.so
-rw-r--r-- 1 liucx liucx   4154 4月   2 15:14 libktest_api.h
-rwxr-xr-x 1 liucx liucx     69 4月   2 15:13 build.sh
-rw-r--r-- 1 liucx liucx    163 4月   2 15:13 libktest.kt
liucx@liucx-QiTianM428-N000:~/Documents/kotlin_demo/lib_file/k_lib/debug$ ./cmain.exe 
Hello, Kotlin!

main.c为C代码和cmain.exe为编译的可执行程序。

C代码调用kotlin native编译的动态库很方便,直接包含头文件,链接对应动态库即可。

由此看来,kotlin-native本身生成的native动态库,被native使用时很方便,基本和native使用方式一致。需要考虑的是kotlin编写的native动态库主要需要考虑接口设计时的参数传递。

kotlin调用native动态库时,需要额外的处理生成klib形式的中间文件,以供kotlin-native编译kt文件时使用。kotlin-native编译kt需要klib的中间文件, 仅仅用于编译,最终的可执行程序运行时只依赖于so动态库

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

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

相关文章

【教学类-102-02】自制剪纸图案(留白边、沿线剪)02——Python+PS自动化添加虚线边框

背景需求: 01版本实现了对透明背景png图案边界线的扩展,黑线实线描边 【教学类-102-01】自制剪纸图案(留白边、沿线剪)01-CSDN博客文章浏览阅读974次,点赞15次,收藏7次。【教学类-102-01】自制剪纸图案(留白边、沿线剪)01https://blog.csdn.net/reasonsummer/article…

Python-函数参数

1. 参数基础 函数参数是向函数传递数据的主要方式,Python 提供了多种参数传递机制。 基本用法 def greet(name): # name 是形式参数print(f"Hello, {name}!")greet("Alice") # "Alice" 是实际参数使用场景:当函数需要…

《在 Ubuntu 22.04 上安装 CUDA 11.8 和 Anaconda,并配置环境变量》

安装 CUDA 11.8 和 Anaconda 并配置环境变量 在本教程中,我们将介绍如何在 Ubuntu 22.04 上安装 CUDA 11.8 和 Anaconda,并配置相应的环境变量。我们还将配置使用 阿里云镜像源 来加速软件包更新。以下是具体步骤。 步骤 1:更新软件源 首先…

Ubuntu环境基于Ollama部署DeepSeek+Open-Webui实现本地部署大模型-无脑部署

Ollama介绍 Ollama是一款简单好用的模型部署工具,不仅可以部署DeepSeek,市面上开源模型大部分都可以一键部署,这里以DeepSeek为例 官网 DeepSeek 版本硬件要求 安装Ollama 环境 sudo apt update sudo apt install curl sudo apt install lsof1.命令一键安装 在官网点击…

Angular 项目 PDF 批注插件库在线版 API 示例教程

本文章介绍 Angular 项目中 PDF 批注插件库 ElasticPDF 在线版 API 示例教程,API 包含 ① 导出批注后PDF数据;② 导出纯批注 json 数据;③ 加载旧批注;④ 切换文档;⑤ 切换用户;⑥ 清空批注 等数据处理功能…

Spring Boot 中利用 Jasypt 实现数据库字段的透明加密解密

1. 引言 1.1 什么是 Jasypt Jasypt(Java Simplified Encryption)是一个用于简化 Java 应用程序中加密操作的库。 1.2 为什么使用 Jasypt 简化加密操作:提供简单的 API 进行加密和解密。透明加密:自动处理加密和解密过程,无需手动干预。多种加密算法:支持多种加密算法,…

Linux的: /proc/sys/net/ipv6/conf/ 笔记250405

Linux的: /proc/sys/net/ipv6/conf/ /proc/sys/net/ipv6/conf/ 是 Linux 系统中用于 动态配置 IPv6 网络接口参数 的核心目录。它允许针对不同网络接口(如 eth0、wlan0)或全局设置(all)调整 IPv6 协议栈的行为。 它通过虚拟文件系…

Spring Cloud 框架为什么能处理高并发

Spring Cloud框架能够有效处理高并发场景,核心在于其微服务架构设计及多组件的协同作用,具体机制如下: 一、分布式架构设计支撑高扩展性 服务拆分与集群部署 Spring Cloud通过微服务拆分将单体系统解耦为独立子服务,每个服务可独…

无人机智慧路灯杆:智慧城市的‘全能助手’

在城市发展的进程中,智慧路灯杆作为智慧城市建设的关键载体,正逐步从传统的照明设备转型为集多种功能于一体的智能基础设施。无人机与智慧路灯杆的创新性融合,为城市管理和服务带来了全新的变革与机遇。 一、无人机智慧路灯杆的功能概述 照…

Libevent UDP开发指南

UDP 与 TCP 的核心区别 无连接:不需要建立/维护连接 不可靠:不保证数据包顺序和到达 高效:头部开销小,没有连接管理负担 支持广播/多播:可以向多个目标同时发送数据 一、基础UDP服务器实现 1. 创建 UDP 套接字 #include <event2/event.h> #include <event2/lis…

基于阿里云可观测产品构建企业级告警体系的通用路径与最佳实践

前言 1.1 日常生活中的告警 任何连续稳定运行的生产系统都离不开有效的监控与报警机制。通过监控&#xff0c;我们可以实时掌握系统和业务的运行状态&#xff1b;而报警则帮助我们及时发现并响应监控指标及业务中的异常情况。 在日常生活中&#xff0c;我们也经常遇到各种各样…

智能多媒体处理流水线——基于虎跃办公API的自动化解决方案

在内容爆炸的时代&#xff0c;多媒体文件处理&#xff08;图片压缩、视频转码、音频降噪&#xff09;已成为内容生产者的日常挑战。本文将演示如何基于虎跃办公的多媒体处理API&#xff0c;构建自动化处理流水线&#xff0c;实现&#xff1a; 批量文件智能分类格式自动转换质量…

01-STM32(介绍、工具准备、新建工程)p1-4

文章目录 工具准备和介绍硬件设备stm32简介和arm简介stm32简介STM32命名规则STM32选型STM32F103C8T6最小系统板引脚定义STM32启动配置STM32最小系统电路ARM简介 软件安装注册器件支持包安装ST-LINK驱动安装USB转串口驱动 新建工程创建stm32工程STM32工程编译和下载型号分类及缩…

【ABAP】REST/HTTP技术(一)

1、概念 1.1、SAP 如何提供 Http Service 如果要将 SAP 应用程序服务器 &#xff08;application server&#xff09;作为 http 服务提供者&#xff0c;需要定义一个类&#xff0c;这个类必须实现 IF_HTTP_EXTENSION 接口。IF_HTTP_EXTENSION 接口只有一个方法 HANDLE_REQUEST。…

[实战] linux驱动框架与驱动开发实战

linux驱动框架与驱动开发实战 Linux驱动框架与驱动开发实战一、Linux驱动框架概述1.1 Linux驱动的分类1.2 Linux驱动的基本框架 二、Linux驱动关键API详解2.1 模块相关API2.2 字符设备驱动API2.3 内存管理API2.4 中断处理API2.5 PCI设备驱动API 三、Xilinx XDMA驱动开发详解3.1…

1. hadoop 集群的常用命令

1.上传文件 1)hadoop fs -put words.txt /path/to/input/ 2)hdfs dfs -put words.txt /path/wc/input/ 2.获取hdfs中的文件 hadoop fs -get /path/wc/input/words.txt 3.合并下载多个文件 hadoop fs -getmerge /path/wc/input/words.txt /path/wc/input/words2.txt 4.查…

Keepalived+LVS+nginx高可用架构

注明&#xff1a;所有软件已经下载好&#xff0c;防火墙和SELinux已经全部关闭 一.搭建NFS 1.服务端 1.创建文件 [rootnfs ~]# mkdir -p /nfs/data 2、修改权限 [rootnfs ~]# chmod orw /nfs/data 3、写配置文件 [rootnfs ~]# cat /etc/exports /nfs/data 192.168.111.118(r…

深度学习处理文本(13)

我们使用基于GRU的编码器和解码器来在Keras中实现这一方法。选择GRU而不是LSTM&#xff0c;会让事情变得简单一些&#xff0c;因为GRU只有一个状态向量&#xff0c;而LSTM有多个状态向量。首先是编码器&#xff0c;如代码清单11-28所示。 代码清单11-28 基于GRU的编码器 fro…

HashMap 底层原理详解

1. 核心数据结构 JDK 1.7 及之前&#xff1a;数组 链表 JDK 1.8 及之后&#xff1a;数组 链表/红黑树&#xff08;链表长度 ≥8 时转红黑树&#xff0c;≤6 时退化为链表&#xff09; // JDK 1.8 的 Node 定义&#xff08;链表节点&#xff09; static class Node<K,V&g…

使用MySQL时出现 Ignoring query to other database 错误

Ignoring query to other database 错误 当在远程连接软件中输入MySQL命令出现该错误 导致错误原因是&#xff1a;登录mysql时账户名没有加上u 如果出现该错误&#xff0c;退出mysql&#xff0c;重新输入正确格式进入即可&#xff01;