Kotlin JVM JNI C++ Inheritance and Callback using SWIG

Submitted by Dickens A S on Tue, 07/20/2021 - 03:59

Based on Article kotlin-jni-swig-gradle-cpp

This Article demonstrates how to Inherit class from C++ class and how to make C++ calls back the Kolin function using overriding

GitHub: https://github.com/dickensas/kotlin-gradle-templates/tree/master/swig-jni-inherit-callback

For C Pointer Refer Article kotlin-swig-jni-arrays-and-pointers

The Gradle SWIG Task of cpplib

val swigTask: Exec by tasks.creating(Exec::class) {
    commandLine (
        "swig",
        "-c++",
        "-java",
        "-cppext",
        "cpp",
        "-addextern",
        "-directors",
        "-module",
        "${project.name}",
        "src\\main\\swig\\${project.name}.i"
    )
}

this code is written generic based on the folder name of the sub project is assumed as the DLL file name

These gradle tasks plays the important role, otherwise you need to manually copy the files

The Kotlin Code

class KotlinCallback : Callback {
    constructor(): super() {
        
    }
    override fun run()
    {
        println("From Kotlin KotlinCallback::run()");
    }
}

class App {
    fun demo() {
        var callback = KotlinCallback()
        var caller = Caller()
        caller.setCallback(callback)
        caller.call()
        caller.delCallback()
    }
        
    companion object {
        init {
            System.loadLibrary("cpplib")
        }
    }
}

fun main(args: Array<String>) {
    App().demo()
    
}

The C++ Code

/*
 * This C++ source file was generated by the Gradle 'init' task.
 */

#include <iostream>
#include <stdlib.h>
#include "cpplib.h"

void jniexample::Callback::run() {
    std::cout << "From C++ Callback::run()" << std::endl;
}

jniexample::Callback::~Callback() { 
    std::cout << "From C++ Callback::~Callback()" << std:: endl; 
}

jniexample::Caller::~Caller() {
    delCallback();
}

void jniexample::Caller::delCallback() { 
    delete _callback; 
    _callback = 0; 
}

void jniexample::Caller::setCallback(Callback *cb) { 
    delCallback(); 
    std::cout << "From C++ Setting callback" << std:: endl; 
    _callback = cb; 
}

void jniexample::Caller::call() { 
    if (_callback) { 
        _callback->run();
    } 
}

The SWIG Code

%{
#include "../public/cpplib.h"
%}

%include "../public/cpplib.h"

Output

> Task :run
From C++ Setting callback
From Kotlin KotlinCallback::run()
From C++ Callback::~Callback()

Here the C++ calls the kotlin function "run" through inheritance override

Finished!

 

Add new comment