Skip to content

Commit be15331

Browse files
committed
Update main to output generated at aacb1e6
1 parent a26b707 commit be15331

2 files changed

Lines changed: 33 additions & 28 deletions

File tree

foundation/kotlin-compiler-learn/kotlin-c-interop/index.html

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -946,10 +946,10 @@
946946

947947
<li class="md-nav__item">
948948
<a href="#_2" class="md-nav__link">
949-
绑定生成
949+
绑定与桥接生成
950950
</a>
951951

952-
<nav class="md-nav" aria-label="绑定生成">
952+
<nav class="md-nav" aria-label="绑定与桥接生成">
953953
<ul class="md-nav__list">
954954

955955
<li class="md-nav__item">
@@ -986,20 +986,14 @@
986986
构建桥接代码
987987
</a>
988988

989-
</li>
990-
991-
</ul>
992-
</nav>
993-
994989
</li>
995990

996991
<li class="md-nav__item">
997992
<a href="#_6" class="md-nav__link">
998993
原生代码编译
999994
</a>
1000995

1001-
<nav class="md-nav" aria-label="原生代码编译">
1002-
<ul class="md-nav__list">
996+
</li>
1003997

1004998
<li class="md-nav__item">
1005999
<a href="#klib" class="md-nav__link">
@@ -1019,8 +1013,8 @@
10191013
</li>
10201014

10211015
<li class="md-nav__item">
1022-
<a href="#cinterop" class="md-nav__link">
1023-
调试 CInterop 过程
1016+
<a href="#ccall" class="md-nav__link">
1017+
编译器处理 @CCall 函数调用
10241018
</a>
10251019

10261020
</li>
@@ -2580,10 +2574,10 @@
25802574

25812575
<li class="md-nav__item">
25822576
<a href="#_2" class="md-nav__link">
2583-
绑定生成
2577+
绑定与桥接生成
25842578
</a>
25852579

2586-
<nav class="md-nav" aria-label="绑定生成">
2580+
<nav class="md-nav" aria-label="绑定与桥接生成">
25872581
<ul class="md-nav__list">
25882582

25892583
<li class="md-nav__item">
@@ -2620,20 +2614,14 @@
26202614
构建桥接代码
26212615
</a>
26222616

2623-
</li>
2624-
2625-
</ul>
2626-
</nav>
2627-
26282617
</li>
26292618

26302619
<li class="md-nav__item">
26312620
<a href="#_6" class="md-nav__link">
26322621
原生代码编译
26332622
</a>
26342623

2635-
<nav class="md-nav" aria-label="原生代码编译">
2636-
<ul class="md-nav__list">
2624+
</li>
26372625

26382626
<li class="md-nav__item">
26392627
<a href="#klib" class="md-nav__link">
@@ -2653,8 +2641,8 @@
26532641
</li>
26542642

26552643
<li class="md-nav__item">
2656-
<a href="#cinterop" class="md-nav__link">
2657-
调试 CInterop 过程
2644+
<a href="#ccall" class="md-nav__link">
2645+
编译器处理 @CCall 函数调用
26582646
</a>
26592647

26602648
</li>
@@ -2706,7 +2694,7 @@ <h2 id="_1">接口定义</h2>
27062694
compilerOpts = -Isrc/nativeInterop/cinterop
27072695
</code></pre>
27082696
<p>如上所示,<code>.def</code> 文件定义了 C 接口,包括头文件、编译选项、链接选项等信息。C-interop 工具将解析这个文件,并生成相应的 Kotlin 代码和 KLIB 文件。</p>
2709-
<h2 id="_2">绑定生成</h2>
2697+
<h2 id="_2">绑定与桥接生成</h2>
27102698
<pre><code>./kotlin-native/dist/bin/run_konan cinterop -def ./compilerTestData/cinterop/hello.def -o compilerTestData/cinterop/Hello -J&quot;-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:50015&quot;
27112699
</code></pre>
27122700
<p>当我们执行 C-interop 命令时,实际上是调用了以上命令,这个命令会执行以下操作:</p>
@@ -2804,7 +2792,7 @@ <h4 id="_5">构建桥接代码</h4>
28042792
// 这样 Kotlin 代码就可以通过这个函数指针安全地调用 C 函数
28052793
const void* knifunptr_hello0_hello_from_c = (const void*)&amp;hello_hello_from_c_wrapper0;
28062794
</code></pre>
2807-
<h3 id="_6">原生代码编译</h3>
2795+
<h4 id="_6">原生代码编译</h4>
28082796
<p>上面生成的 C 桥接代码,需要通过 LLVM 编译为 bc 文件。</p>
28092797
<pre><code>when (flavor) {
28102798
KotlinPlatform.NATIVE -&gt; {
@@ -2836,10 +2824,27 @@ <h4 id="klib">生成 KLIB</h4>
28362824
}
28372825
}
28382826
</code></pre>
2839-
<h2 id="cinterop">调试 CInterop 过程</h2>
2840-
<pre><code>./kotlin-native/dist/bin/run_konan cinterop -def ./compilerTestData/cinterop/hello.def -o compilerTestData/cinterop/Hello -J&quot;-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:50015&quot;
2827+
<h2 id="ccall">编译器处理 @CCall 函数调用</h2>
2828+
<p>上面生成的 KLIB 文件,包含了 Kotlin IR 存根和桥接代码。接下来,Kotlin 编译器会处理这个 KLIB 文件,将其与 Kotlin 代码进行链接。通过以下命令行执行 Kotlin 编译器:</p>
2829+
<pre><code>./kotlin-native/dist/bin/run_konan konanc ./compilerTestData/cinterop/Main.kt -library ./compilerTestData/cinterop/Hello.klib -o ./compilerTestData/cinterop/Hello -J&quot;-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:50015&quot;
2830+
</code></pre>
2831+
<p>同时我们可以看到,上面生成的 knm 中的函数为<code>hello_from_c</code>,而生成的桥接代码中的函数是<code>knifunptr_hello0_hello_from_c</code>,因此 Kotlin 编译器还需要识别<code>@kotlinx.cinterop.internal.CCall</code>函数,并修改调用代码,将其替换为桥接函数。</p>
2832+
<pre><code class="language-kotlin">// 处理 C 函数调用
2833+
if (function.annotations.hasAnnotation(RuntimeNames.cCall)) {
2834+
return generateCCall(expression)、
2835+
}
28412836

2842-
./kotlin-native/dist/bin/run_konan konanc ./compilerTestData/cinterop/Main.kt -library ./compilerTestData/cinterop/Hello.klib -o ./compilerTestData/cinterop/Hello -J&quot;-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:50015&quot;
2837+
generateCCall(expression: IrCall, builder: IrBuilderWithScope, isInvoke: Boolean,
2838+
foreignExceptionMode: ForeignExceptionMode.Mode = ForeignExceptionMode.default): IrExpression {
2839+
// ...
2840+
if (isInvoke) {
2841+
callBuilder.cBridgeBodyLines.add(0, &quot;$targetFunctionVariable = ${targetPtrParameter!!};&quot;)
2842+
} else {
2843+
val cCallSymbolName = callee.getAnnotationArgumentValue&lt;String&gt;(RuntimeNames.cCall, &quot;id&quot;)!!
2844+
this.addC(listOf(&quot;extern const $targetFunctionVariable __asm(\&quot;$cCallSymbolName\&quot;);&quot;)) // Exported from cinterop stubs.
2845+
}
2846+
return result
2847+
}
28432848
</code></pre>
28442849

28452850
<hr>

search/search_index.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)