2017-05-18 23:32:18 ztguang 阅读数 1227
  • 征服Kotlin视频教程

    该课程包括Kotlin开发环境搭建、Kotlin基础知识、类和接口、枚举类、扩展、泛型、函数、lambdas表达式、对象、标准API等。

    8157 人正在学习 去看看 李宁


https://www.qingjingjie.com/blogs/48


很高兴Kotlin在前两天发布了Kotlin/Native的Tech Preview版本。Kotlin/Native能把Kotlin编译成机器码,也就是C/C++、Go和Rust的层次,于是这个领域又添一位竞争对手。

JetBrains是一家务实的公司,它家的各种IDE让人赞不绝口。它创造的Kotlin也是一门务实的编程语言,借鉴Java和Scala的精华,以实用性为导向。

Kotlin的宣传语是“100%可与Java互操作”,事实证明确实如此,极低的学习成本和采用成本,极高的开发效率提升,在Android上已经火得不得了了,我在服务器上也用得很开心。现在Kotlin编译到机器码,不运行在JVM,就不能沿用Java的生态系统了,而是要融入系统编程的生态系统。Kotlin也的确是想做一个高性能的“胶水”。在这个领域,失去了JVM的庇佑,却得到了新的力量。

Kotlin已经实现了编译到JavaScript,现在又编译到机器码,野心不可谓不大。它的实力能否匹配野心呢?从JetBrains的 博客 来看,他们对Kotlin/Native也是很务实的态度,所以这个项目是值得期待的。技术预览版来了,Alpha和Beta还会远吗?欢欣鼓舞!

Kotlin/Native利用LLVM来编译到机器码,现在已支持4个平台:

  • Linux (暂时只是Ubuntu),
  • Mac OS
  • iOS
  • Raspberry Pi

这意味着开发者们已经可以愉快地开始体验了!

Kotlin/Native仍然很看重互操作性(Interoperability)。它能高效地调用C函数,甚至还能从C头文件自动生成对应的Kotlin接口,发扬了JetBrains为开发者服务的良好传统!

关于内存管理,现在的计划是在不同平台使用各自适合的内存管理技术,例如在服务器和桌面平台倾向于使用追踪式垃圾回收(tracing GC),而在iOS则倾向于使用iOS已有的ARC技术。在某些平台则可能手动管理内存。现在的Tech Preview版本只提供了一种附带循环检测的引用计数式内存管理,但并没有决定最终会怎样选择内存管理技术。

这个版本基本上没做什么优化,所以在benchmark中可能会表现得不好。但是一定会努力优化,用实际数据说话,而不会拿理论来忽悠人。标准库和反射功能也还远未完成,但是愿意做这些东西已经让我觉得很良心了。

博客中列出的未来计划包括:

  • 进军iOS
  • 进军嵌入式系统和物联网
  • 进军数据分析和科学计算
  • 进军服务端和微服务
  • 进军游戏开发

进军iOS意味着要在移动端全制霸,而且还想进军这么多领域,似乎盘子有点太大了。我希望他们能把JavaScript先放下,毕竟很多语言都在这里折戟了,还记得当年的GWT吗?不如在Native层多多发力,先定一个小目标——抢Go语言的盘子。


2018-08-22 04:30:53 cpongo2 阅读数 49
  • 征服Kotlin视频教程

    该课程包括Kotlin开发环境搭建、Kotlin基础知识、类和接口、枚举类、扩展、泛型、函数、lambdas表达式、对象、标准API等。

    8157 人正在学习 去看看 李宁

在这篇博文中,我们将讨论Kotlin/Native应用程序的开发。在这里,我们使用FFMPEG音频/视频解码器和SDL2进行渲染,来开发个简易的视频播放器。希望此文可以成为能对Kotlin/Native开发者有价值的开发指南,同时该文也会解释使用该平台的预期机制。

\u0026#xD;\u0026#xD;

在本教程中,我们主要关注的是Kotlin/Native,我们只会粗略地介绍一下如何开发视频层。您可以参阅这篇名为《如何用不到1000行代码编写一个视频播放器》的优秀教程,以了解如何用C语言实现它。如果您的兴趣点在于比较C语言的编码与Kotlin/Native编码的不同之处,我建议您从本教程开始。

\u0026#xD;\u0026#xD;

理论上,每一个视频播放器的工作都相当简单:读入带有交错的视频帧和音频帧的输入流,解码并显示视频帧,同时与音频流同步。通常,这一工作由多个线程完成,执行流解码、播放视频和音频。要准确的做到这些,需要线程同步和特定的实时保证,如果音频流没有被及时解码,播放声音听起来会很不稳定,如果视频帧没有及时显示,影像看起来会很不流畅。

\u0026#xD;\u0026#xD;

Kotlin/Native不鼓励您使用线程,也不提供在线程之间共享Kotlin对象的方法。然而,我们相信在Kotlin/Native中并发的软实时编程很容易实现,所以我们决定从一开始就以并发的方式来设计我们的播放器。来看看我们是怎么做到的吧。

\u0026#xD;\u0026#xD;

Kotlin/Native计算并发性是围绕workers构建的。Worker是比线程更高级的并发性概念,不像对象共享和同步,它允许对象传输,因此每一时刻只有一个workers可以访问特定对象。这意味着,访问对象数据时不需要同步,因为多个访问永远不能同时进行。workers可以接收执行请求,这些请求可以接受对象并根据需要执行任务,然后将结果返回给需要计算结果的人。这样的模型确保了许多典型的并发编程错误(例如对共享数据的不同步访问,或者由未排序的锁导致的死锁)不再出现。

\u0026#xD;\u0026#xD;

让我们看看,它是如何转化为视频播放器架构的。我们需要对某些容器格式进行解码,比如avi.mkv或者 .mpg,它对交叉音频和视频流进行多路分解、解码,然后将解压缩的音频提供给SDL音频线程。解压后的视频帧应与声音播放同步。为了达到这个目标,worker概念的出现也便是理所当然的了。我们为解码器生成一个worker,并在需要的时候向它请求视频音频数据。在多核机器上,这意味着解码可以与播放并行进行。因此,解码器是一个来自UI线程和音频线程的数据生成器。

\u0026#xD;\u0026#xD;

无论何时我们需要获取下一个音频或视频数据块时,我们都依赖于全能的schedule()函数。它将调度大量的工作给特定的worker执行,以便提供输入参数和返回Future实例,这些可能被挂起,直到任务被目标worker执行完。Future对象可能被销毁,因此产生的对象将直接从worker线程返回到请求程序线程。

\u0026#xD;\u0026#xD;

Kotlin/Native运行时理论上讲是线性的,所以当运行多个线程时,需要在做其他操作之前调用函数konan.initRuntimeIfNeeded(),我们在音频线程回调中也是这样做的。为了简化音频播放,我们将音频帧重新采样到两个通道,并以44100的采样率对16位整数流进行标识

\u0026#xD;\u0026#xD;

视频帧可以被解码成用户需要的大小,当然它会有个默认值,同时它的位深度依赖于用户桌面默认设置。还请注意下Kotlin/Native特有的操作C指针的方法,即

\u0026#xD;\u0026#xD;
\u0026#xD;private val resampledAudioFrame: AVFrame =\u0026#xD;        disposable(create = ::av_frame_alloc, dispose = ::av_frame_unref).pointed\u0026#xD;...\u0026#xD;with (resampledAudioFrame) {\u0026#xD;    channels = output.channels\u0026#xD;    sample_rate = output.sampleRate\u0026#xD;    format = output.sampleFormat\u0026#xD;    channel_layout = output.channelLayout.signExtend()\u0026#xD;}
\u0026#xD;\u0026#xD;

我们声明resampledAudioFrame作为由FFMPEG API调用avframealloc()和avframeunref()创建的C程序中的一次性资源。然后,我们将它所指向的值设置成它所期望的字段。需要注意的是,我们可以将FFMPEG(如AV_PIX_FMT_RGB24)声明的定义作为Kotlin的常量。但是,由于它们没有类型信息,并且默认情况下是Int类型的,如果某个字段具有不同的类型(比如channellayout),那便需要调用适配器函数signExtend()。这是编译器的内在特性,它会插入适当的转换中

\u0026#xD;\u0026#xD;

在设置完解码器后,我们开始播放流程。这没有什么特别的,只是检索下一个帧,将它呈现给纹理,并在屏幕上显示这个纹理。至此,视频帧便被渲染了。音频线程回调是由音频线程回调处理的,它从解码器中获取下一个采样缓冲区,并将其反馈给音频引擎。

\u0026#xD;\u0026#xD;

音频/视频同步是必须要保证的,它可以确保我们没有太多的未播放的音频帧。真正的多媒体播放器应该依赖于帧时间戳,我们只计算它,但永远不会使用。这里有一个有趣的地方

\u0026#xD;\u0026#xD;
\u0026#xD;val ts = av_frame_get_best_effort_timestamp(audioFrame.ptr) * \u0026#xD;  av_q2d(audioCodecContext.time_base.readValue())
\u0026#xD;\u0026#xD;

它展示了如何使用api接收C语言的结构体。它是在libavutil/rational.h中声明的

\u0026#xD;\u0026#xD;
\u0026#xD;static inline double av_q2d(AVRational a){\u0026#xD;    return a.num / (double) a.den;\u0026#xD;}
\u0026#xD;\u0026#xD;

因此,要通过值传递它,我们首先需要在字段上使用readValue()。

\u0026#xD;\u0026#xD;

总结来说,多亏了FFMPEG库,我们才能用较少的代价便实现了一个支持多种输入格式的简易音频/视频播放器。这里我们还讨论了Kotlin/Native中基于C语言的互操作性相关的基础知识,以及更容易使用和维护的并发方法。 

\u0026#xD;\u0026#xD;

英文原文链接Application development in Kotlin/Native

\u0026#xD;\u0026#xD;

感谢冬雨对本文的审校。

2017-11-08 09:10:16 kwame211 阅读数 1742
  • 征服Kotlin视频教程

    该课程包括Kotlin开发环境搭建、Kotlin基础知识、类和接口、枚举类、扩展、泛型、函数、lambdas表达式、对象、标准API等。

    8157 人正在学习 去看看 李宁

KotlinConf 大会宣布了 Kotlin 1.2 RC 版,并宣布 Kotlin/Native 已支持用于开发 iOS 应用和 Web 应用开发。

近日,首届官方举办的 Kotlin 专题会议 KotlinConf 正式开幕,来自世界各地约 1200 名与会者齐聚旧金山,在这场盛大的 KotlinConf 大会主题演讲中,Kotlin 的首席语言设计师 Andrey Breslav 公布了一系列与 Kotlin 紧密相关的重大发展成果。接下来,我们不妨关注一下。

Kotlin 1.2 RC

首先宣布了 Kotlin 1.2 RC 版(即 1.2 首个候选发行版)。该版本引入了一系列新功能,包括对多平台项目的实验性支持 —— 允许开发者在针对 JVM 和 JavaScript 的模块之间共享代码,以及多项对语言方面的改进 —— 包括支持在注释中使用数组字面量。更多关于 1.2 版本新功能的内容,可点击此处查看:https://blog.jetbrains.com/kotlin/2017/09/kotlin-1-2-beta-is-out

此外,值得关注的就是协程这个特性了。虽然协程仍然被标记为实验性状态,但官方特意说明了这里“实验性”代表的含义。官方表示协程已经完全准备好用于生产环境,他们也已使用协程进行开发,而且也没发现在使用当中出现任何重大问题。之所以仍保持实验性状态,是为了能够对 Kotlin 继续进行设计迭代。根据目前的计划,Kotlin 1.3 将会删除协程的实验性状态。

Kotlin/Native 对 iOS 开发的支持

另外一个重大消息就是 Kotlin/Native 已支持用于开发 iOS 应用,这也将是 Kotlin/Native 0.4 的特性之一。虽然对 iOS 开发的支持仍处于早期阶段,但确实已经实现了,这是在所有平台上使用 Kotlin 进行开发的重要一步。

官方还特意展示了利用 Kotlin/Native 开发的两款应用(Spinner app (GitHub)、KotlinConf app (GitHub)),它们都可以运行于 iOS 和 Android 平台。Android 和 iOS 平台共享了不少代码,其中包括大多数图形处理、声音播放和用户输入响应代码。

两款应用都已开源,你可以将它们作为模板,仅使用 Kotlin 构建自己的跨平台移动应用。点此此处可了解其中一款应用:https://www.oschina.net/p/kotlinconf-spinner

IDE 对 Kotlin/Native 的支持

Kotlin/Native 也将迎来 IDE 的支持。官方表示首先将在 C/C++ IDE CLion 中试用该功能,目前正在发布一个名为 Kotlin/Native plugin for CLion 的插件,该插件支持使用 CMake 作为构建系统。其中包含来自 IntelliJ IDEA 的 Kotlin 插件中全部代码编辑功能集,同时初步支持项目创建、测试与调试等操作。

使用 React 和 Kotlin 创建现代 Web 应用

对于使用 Kotlin 进行 Web 前端开发的开发者,Andrey Breslav 在大会上还公布了另外一个重大消息 —— 正式发布了针对 React.js 的官方 Kotlin 封装工具。此外,还有一个名为 create-react-kotlin-app 的工具集 —— 通过 Kotlin 使用 React.js 创建现代 Web 应用。

使用 create-react-kotlin-app,可让开发者无需费心于项目设置和配置构建这些工作,能专注于快速开始客户端应用开发,同时体会到静态类型语言的优势以及由 JavaScript 生态系统带来的强大配套资源。详情点此了解:https://github.com/JetBrains/create-react-kotlin-app

未来的发展方向

Kotlin 语言的未来发展方向主要是在 Kotlin 支持的平台之间实现更好、更广泛的代码重用。官方表示计划通过使用同一 API 以扩展全部平台上的可用库资源集合,其中涵盖 I/O、网络、序列化以及日期处理等。

编译器方面,1.3 版本仍集中关注内部层面的变更,而不是外部可见的语言特性。内部的改变能提高性能、改进类型推断、为所有目标平台生成更高效的代码,以及带来更好的 IDE 插件响应能力。

关于 Kotlin/Native

说了这么多,Kotlin/Native 到底是什么?Kotlin/Native 能将 Kotlin 编译成机器码,目前还处于技术预览版阶段,离商用估计还需要至少一年的时间。

Kotlin/Native 不是 Jni 的概念,它不仅仅是要与底层代码比如 C、C++ 交互,而且还要绕过 JVM 直接编译成机器码供系统运行。这说明了什么?Kotlin 准备扔掉 Java 这根拐杖了。

第一次看到 Native 这个名字或许会很自然地想到 Jni,Kotlin 跑在 JVM 上面,使用 Jni 与底层代码交互。不过详细深入研究后可以发现,Kotlin 开发团队的野心不可小觑,Java 诞生这么多年,也没有涉足过编译成除 Java 虚拟机字节码以外的字节码的事情,Kotlin 才这么年轻,不得不说十分具有革命性。

所以如果有人再问你什么是 Kotlin,你应该回答,Kotlin 是一门很厉害的静态语言(而不是之前常说的 Kotlin 是一门运行在 JVM 之上的静态语言)。反正你能想到的,Kotlin 的开发团队都想干。

时钟拨回到到五个月前,2017 年 5 月 17 日 Google I/O 大会第一天,谷歌宣布 Kotlin 成为 Android 开发的官方支持语言。有了 JetBrains 和 Google 的背书,自此,对于“Kotlin 即将取代 Java ”的声音从未停止过。曾经,CSDN 也曾发表过一篇题为“5 个月策反,Kotlin 将取代 Java 成 Android 开发第一语言?”的文章,文中提到,Realm 公司调查报告给出的预测表示,“到 2018 年底,在 Android 开发领域,Kotlin 将超越 Java,成为开发 Android 应用的第一语言。”

不过,再看回在 KotlinConf 大会中官方已公布的关于 Kotlin 的发展成果和未来方向,Kotlin 的目标可能并不是撼动常青藤 Java 在 Android 开发领域中的地位,他们的征途或许是星辰大海。

2018-05-19 07:18:18 weixin_34252686 阅读数 55
  • 征服Kotlin视频教程

    该课程包括Kotlin开发环境搭建、Kotlin基础知识、类和接口、枚举类、扩展、泛型、函数、lambdas表达式、对象、标准API等。

    8157 人正在学习 去看看 李宁

Kotlin/Native

Kotlin/Native是Kotlin的本地化构建工具,可以为Kotlin提供C的互操作性以及将Kotin开发应用编译成本地化的可执行程序。

Kotlin/Native 支持mac、linux、win32等多个平台,本文主要将以win32平台为主要介绍

使用Gradle构建

Gradle构建文件

创建hello/src/main/kotlin/build.gradle:

buildscript {
    repositories {
        mavenCentral()
        maven {
            url "http://dl.bintray.com/jetbrains/kotlin-native-dependencies"
        }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.7"
    }
}
// 启用konan插件提供本地化编译支持
apply plugin: 'konan'
// 指定编译平台,windows为mingw,其它包括linux,ios等
konan.targets = ['mingw']
// konan编译应用名
konanArtifacts {
    program('hello')
}

随便写点测试代码

创建hello/src/main/kotlin/main.kt:

/**
 * main方法,程序主入口
 * 注意此处不需要包名
 */
fun main(args: Array<String>) {
    println("Hello Kotlin/Native with Gradle!")
}

使用Gradle构建

目前的项目结构应该是这样的:

hello
--build.gradle
--src
----main
------kotlin
--------main.kt

BUILD它!

在hello目录下执行:

gradle build

如果幸运的话,你将看到构建成功的信息:

$ gradle build
> Task :assemble UP-TO-DATE
> Task :check UP-TO-DATE
> Task :checkKonanCompiler
> Task :compileKonanHelloMingw_x64
> Task :compileKonanHello
> Task :compileKonan
> Task :build

BUILD SUCCESSFUL in 5s
2 actionable tasks: 2 executed

Build成功后在hello文件夹下会发现有新增的build文件夹,其包括了编译后的输出文件,一般我们的可执行文件会在这个路径下:
hello/build/konan/bin/mingw_x64/hello.exe
运行他看看?

$ cd build/konan/bin/mingw_x64/
$ ./hello
Hello Kotlin/Native with Gradle!

然后呢?

至此,我们已经初步掌握了使用kotlin/Native构建的方法,接下来让我们试着写点什么吧!

2019-02-05 14:45:03 weixin_33744854 阅读数 255
  • 征服Kotlin视频教程

    该课程包括Kotlin开发环境搭建、Kotlin基础知识、类和接口、枚举类、扩展、泛型、函数、lambdas表达式、对象、标准API等。

    8157 人正在学习 去看看 李宁

Kotlin/Native尝试

在官网看到Kotlin/Native已经达到1.0 Beta版于是就去尝试了一下,结果发现坑还是挺多的。
首先Kotlin/JVM很多库是用不了的,这个已经猜到了。官网说已经预先导入了 POSIX、 gzip、 OpenGL、 Metal、 Foundation 等很多其他的库,然后我就尝试了下基本的文件读写。和C还是有一点的差别的。如下:

fun hello(): String = "Hello, Kotlin/Native!"
fun letter() = "abcdefghigklmnopqrstuvwxyz"

fun main(args: Array<String>) {
    val file = fopen("data.txt", "w")
    fprintf(file, "%s", hello())
    fprintf(file, "%s", "\n")
    fprintf(file, "%s", letter())
    fclose(file)
    println("write finished")
    val filer = fopen("data.txt", "r")
    val buf = ByteArray(255)
//    fscanf(filer, "%s", buf.pin().addressOf(0))
    fgets(buf.pin().addressOf(0), 255, filer)
    fclose(filer)
    print(buf.stringFromUtf8())
    buf.pin().unpin()
    println("read finished")
    system("pause")
}

运行结果如下

> Task :runProgram
write finished
Hello, Kotlin/Native!
read finished
Press any key to continue . . . 
C:\BuildAgent\work\4d622a065c544371\runtime\src\main\cpp\Memory.cpp:1150: runtime assert: Memory leaks found

> Task :runProgram FAILED

令人郁闷的是提示C:\BuildAgent\work\4d622a065c544371\runtime\src\main\cpp\Memory.cpp:1150: runtime assert: Memory leaks found,虽然调用了buf.pin().unpin(),但依旧提示内存泄漏,也没有异常退出啊。

如果是改成如下方式就不会提示错误了:

fun hello(): String = "Hello, Kotlin/Native!"
fun letter() = "abcdefghigklmnopqrstuvwxyz"

fun main(args: Array<String>) {
    val file = fopen("data.txt", "w")
    fprintf(file, "%s", hello())
    fprintf(file, "%s", "\n")
    fprintf(file, "%s", letter())
    fclose(file)
    println("write finished")
    val filer = fopen("data.txt", "r")
    val buf = ByteArray(255)
//    fscanf(filer, "%s", buf.pin().addressOf(0))
//    fgets(buf.pin().addressOf(0), 255, filer)
//    fclose(filer)
//    print(buf.stringFromUtf8())
//    buf.pin().unpin()
    buf.usePinned {
        fgets(it.addressOf(0), 255, filer)
        fclose(filer)
        print(buf.stringFromUtf8())
    }
    println("read finished")
    system("pause")
}

结果如下:

> Task :runProgram
write finished
Hello, Kotlin/Native!
read finished
Press any key to continue . . . 

BUILD SUCCESSFUL in 9s

另外吐槽下,这么几行代码就要9s,是不是太慢了。

随后又试了下开启pthread线程,但是pthread_create函数的第一个参数th: kotlinx.cinterop.CValuesRef<platform.posix.pthread_tVar>CValuesRef类型的变量怎么获得一直无解,难道只能通过继承获得?

然后我在写文章的时候又发现只要这样写就可以了???

fun main(args: Array<String>) {
    pthread_create(null, null, test(), null)
}

typealias func = kotlinx.cinterop.CPointer<kotlinx.cinterop.CFunction<(kotlinx.cinterop.COpaquePointer?) -> kotlinx.cinterop.COpaquePointer?>>?

fun test(): func {
    return staticCFunction<kotlinx.cinterop.COpaquePointer?, kotlinx.cinterop.COpaquePointer?> {
        println("run test")
        it
    }
}

结果如下:

> Task :runProgram
run test
BUILD SUCCESSFUL in 8s
没有更多推荐了,返回首页