Search code examples
javac++kotlinjava-native-interface

Using JNI with kotlin gives UnsatisfiedLinkError


I'm trying to use JNI with kotlin to use c++ code in kotlin, but for some reason im getting an UnsatisfiedLinkError even though the signature should be alright since its generated using javah. Any ideas why it would do that?

Kotlin Function Declaration:

external fun initLuaScript(script: String);

javah generated header:

/*
 * Class:     gg_kapilarny_luakt_LuaScript
 * Method:    initLuaScript
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_gg_kapilarny_luakt_LuaScript_initLuaScript
  (JNIEnv *, jobject, jstring);

C++ definition of the function:

JNIEXPORT void JNICALL Java_gg_kapilarny_luakt_LuaScript_initLuaScript(JNIEnv* env, jobject self, jstring script) {
    lua_State* l = luaL_newstate();

    const char* cstr = env->GetStringUTFChars(script, nullptr);
    bool result = checkLua(l, luaL_dostring(l, cstr));
    env->ReleaseStringUTFChars(script, cstr);

    if(!result) {
        std::cout << "LuaKT: Failed to load the script!" << std::endl;
        return;
    } else {
        std::cout << "LuaKT: Successfully loaded the thingy" << std::endl;
    }

    jclass nativeDataClazz = env->FindClass("gg/kapilarny/luakt/NativeData");
    jfieldID fid = env->GetFieldID(nativeDataClazz, "nativeData", "Lgg/kapilarny/luakt/NativeData;");
    jmethodID constructor = env->GetMethodID(nativeDataClazz, "<init>", "(J)V");

    jobject nativeData = env->NewObject(nativeDataClazz, constructor, (jlong) (uintptr_t) l);
    env->SetObjectField(self, fid, nativeData);
}

Solution

  • I figured out the problem!
    The problem was that i did not load the Native DLL.
    Basically i had the library load when the "Main" library class was loaded but i happened to execute a function before the actual DLL load, which caused the error!