微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Kotlin Multiplatform - Objective-C 互操作性架构问题 x86_64 架构的未定义符号

如何解决Kotlin Multiplatform - Objective-C 互操作性架构问题 x86_64 架构的未定义符号

我刚刚尝试使用本机互操作功能,因为我需要在我的库中使用以 Objective-C 编写的本机代码。 所以首先我尝试使用简单的 hello 来测试互操作 Objective-C 代码

毕业:

kotlin {
     ...
 
     val iosX64 = iosX64("ios") {
          compilations.getByName("main) {
              val myInterop by cinterops.creating {
                 defFile(project.file("src/nativeInterop/cinterop/objective-c-file.def"))
              }
          }
     }

     val iosArm32 = iosArm32 ("iosArm32 ") {
          compilations.getByName("main) {
              val myInterop by cinterops.creating {
                 defFile(project.file("src/nativeInterop/cinterop/objective-c-file.def"))
              }
          }
     }

     val iosArm64 = iosArm64("iosArm64") {
          compilations.getByName("main) {
              val myInterop by cinterops.creating {
                 defFile(project.file("src/nativeInterop/cinterop/objective-c-file.def"))
              }
          }
     }

     ...
}

我的 .def 配置:

language = Objective-C
headers = Hello.h Foundation/Foundation.h
package = org.native

compilerOpts = -Isrc/nativeInterop/include

linkerOpts = -framework Foundation "-F/Applications/Xcode 11.3.1.app/Contents/Developer/Platforms/"

这是项目结构的样子

enter image description here

我的Hello.h

#import <Foundation/Foundation.h>

@interface Hello: NSObject

+ (id) init;
- (void) helloObjectiveC;

@end

你好.m

#import "Hello.h"

@implementation Hello

+ (id) init {}
- (void) helloObjectiveC {
    printf("hello Objective c interop")
}

@end

从 gradle 运行 cinterop 任务后,从那个 hello 类生成的 klib,当然现在我可以将它导入到我的 kotlin 项目中。例如在我的 iOS 模块中:

package bca.lib

import org.native.Hello

actual object Platform {

    actual fun getPlatform() = "iOSMain"
    
    fun helloNativeInterop() {
        val hello = Hello()
        hello.helloObjectiveC()
    }

}

然后我试图在我的单元测试中调用它来检查我是否能得到结果,或者我也尝试将它构建到框架但我得到一个错误

> Task :cleanIosTest UP-TO-DATE
> Task :cinteropMyInteropIos UP-TO-DATE
> Task :generateBuildKonfig UP-TO-DATE
> Task :generateIosMainAppDatabaseInterface UP-TO-DATE
> Task :compileKotlinIos UP-TO-DATE
> Task :iosProcessResources UP-TO-DATE
> Task :iosMainKlibrary UP-TO-DATE
> Task :compileTestKotlinIos UP-TO-DATE
> Task :linkDebugTestIos Failed
e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors
Please try to disable compiler caches and rerun the build. To disable compiler caches,add the following line to the gradle.properties file in the project's root directory:
    
    kotlin.native.cacheKind=none
    
Also,consider filing an issue with full Gradle log here: https://kotl.in/issue
The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_Hello",referenced from:
      objc-class-ref in result.o
ld: symbol(s) not found for architecture x86_64
FAILURE: Build Failed with an exception.
* What went wrong:
Execution Failed for task ':linkDebugTestIos'.
> Compilation finished with errors
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build,making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.6.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD Failed in 8s


有谁知道如何解决这个问题,或者不可能以这种方式进行互操作?我只是需要它,以便在我成功将其构建为 .framework 后可以在我的 iOS 应用程序中使用

解决方法

这是一个已知限制,前段时间在 Kotlin 问题跟踪器中有所描述:KT-39562。长话短说,cinterop 工具不提供开箱即用的源文件处理选项。这里最简单的方法是从你的 Objective-C 代码创建一个框架。之后,您将能够以一种简单的方式使用它,如文档中所述。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?