J'ai juste essayé d'utiliser la fonction d'interopérabilité native car j'ai besoin d'un code natif écrit en Objective-C pour être utilisé dans ma bibliothèque. Alors d'abord, j'essaie de tester en utilisant un simple bonjour pour interopérer un code Objective-C

Gradle:

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"))
              }
          }
     }

     ...
}

Ma configuration .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/"

C'est la structure du projet qui ressemble à
entrez la description de l'image ici

Mon Hello.h

#import <Foundation/Foundation.h>

@interface Hello: NSObject

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

@end

Bonjour M

#import "Hello.h"

@implementation Hello

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

@end

Après avoir exécuté la tâche cinterop à partir de gradle, le klib généré à partir de cette classe hello et bien sûr maintenant je peux l'importer dans mon projet kotlin. par exemple dans mon module iOS:

package bca.lib

import org.native.Hello

actual object Platform {

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

}

Ensuite, j'essaye de l'appeler dans mon test unitaire pour vérifier si je peux obtenir le résultat ou j'essaye également de le construire dans le framework mais j'ai eu une erreur:

> 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


Quelqu'un sait comment résoudre ce problème ou peut-être est-il impossible d'interopérer de cette manière? J'en avais juste besoin pour qu'il puisse être utilisé dans mon application iOS plus tard après l'avoir construit avec succès en .framework

1
Davin Reinaldo Gozali 1 mars 2021 à 07:02

1 réponse

Meilleure réponse

Il s'agit d'une limitation connue, décrite dans l'outil de suivi des problèmes Kotlin il y a quelque temps: KT-39562 . En bref, l'outil cinterop ne propose pas d'option pour travailler avec des fichiers source prêts à l'emploi. Le moyen le plus simple ici sera de créer un framework à partir de votre code Objective-C. Après cela, vous pourrez l'utiliser de manière simple, décrite dans la documentation.

1
Artyom Degtyarev 10 mars 2021 à 09:16