Implement very basic Objective-C interop

Also refactor StubGenerator
This commit is contained in:
Svyatoslav Scherbina
2017-07-17 14:34:09 +03:00
committed by SvyatoslavScherbina
parent a38835cb46
commit d3185e3e19
57 changed files with 4020 additions and 920 deletions
+22
View File
@@ -1995,6 +1995,13 @@ kotlinNativeInterop {
linkerOpts '-framework', 'OpenGL', '-framework', 'GLUT'
flavor 'native'
}
objcSmoke {
defFile 'interop/objc/objcSmoke.def'
headers "$projectDir/interop/objc/smoke.h"
linkerOpts "-L$buildDir", "-lobjcsmoke"
flavor 'native'
}
}
}
@@ -2057,4 +2064,19 @@ if (isMac()) {
source = "interop/basics/opengl_teapot.kt"
interop = 'opengl'
}
task interop_objc_smoke(type: RunInteropKonanTest) {
goldValue = "Hello, World!\nKotlin says: Hello, everybody!\nHello from Kotlin\n2, 1\nDeallocated\nDeallocated\n"
source = "interop/objc/smoke.kt"
interop = 'objcSmoke'
doFirst {
execClang {
args "$projectDir/interop/objc/smoke.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', "$buildDir/libobjcsmoke.dylib"
}
}
}
}
@@ -0,0 +1,2 @@
language = Objective-C
headerFilter = **/smoke.h
+24
View File
@@ -0,0 +1,24 @@
#import <objc/NSObject.h>
@protocol Printer
@required
-(void)print:(const char*)string;
@end;
@interface Foo : NSObject
@property NSString* name;
-(void)hello;
-(void)helloWithPrinter:(id <Printer>)printer;
@end;
@protocol MutablePair
@required
@property (readonly) int first;
@property (readonly) int second;
-(void)update:(int)index add:(int)delta;
-(void)update:(int)index sub:(int)delta;
@end;
void replacePairElements(id <MutablePair> pair, int first, int second);
@@ -0,0 +1,55 @@
import kotlinx.cinterop.*
import objcSmoke.*
fun main(args: Array<String>) {
autoreleasepool {
run()
}
}
fun run() {
val foo = Foo()
foo.hello()
foo.name = "everybody"
foo.helloWithPrinter(object : NSObject(), PrinterProtocol {
override fun print(string: CPointer<ByteVar>?) {
println("Kotlin says: " + string?.toKString())
}
})
Bar().hello()
val pair = MutablePairImpl(42, 17)
replacePairElements(pair, 1, 2)
pair.swap()
println("${pair.first}, ${pair.second}")
}
fun MutablePairProtocol.swap() {
update(0, add = second)
update(1, sub = first)
update(0, add = second)
update(1, sub = second*2)
}
class Bar : Foo() {
override fun helloWithPrinter(printer: PrinterProtocol) = memScoped {
printer.print("Hello from Kotlin".cstr.getPointer(memScope))
}
}
@Suppress("CONFLICTING_OVERLOADS")
class MutablePairImpl(first: Int, second: Int) : NSObject(), MutablePairProtocol {
private var elements = intArrayOf(first, second)
override fun first() = elements.first()
override fun second() = elements.last()
override fun update(index: Int, add: Int) {
elements[index] += add
}
override fun update(index: Int, sub: Int) {
elements[index] -= sub
}
}
+46
View File
@@ -0,0 +1,46 @@
#import <stdio.h>
#import <Foundation/NSString.h>
#import "smoke.h"
@interface CPrinter : NSObject <Printer>
-(void)print:(const char*)string;
@end;
@implementation CPrinter
-(void)print:(const char*)string {
printf("%s\n", string);
fflush(stdout);
}
@end;
@implementation Foo
@synthesize name;
-(instancetype)init {
if (self = [super init]) {
self.name = @"World";
}
return self;
}
-(void)hello {
CPrinter* printer = [[CPrinter alloc] init];
[self helloWithPrinter:printer];
}
-(void)helloWithPrinter:(id <Printer>)printer {
NSString* message = [NSString stringWithFormat:@"Hello, %@!", self.name];
[printer print:message.UTF8String];
}
-(void)dealloc {
printf("Deallocated\n");
}
@end;
void replacePairElements(id <MutablePair> pair, int first, int second) {
[pair update:0 add:(first - pair.first)];
[pair update:1 sub:(pair.second - second)];
}