Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how get jni acces? #364

Closed
MatejMagat305 opened this issue Mar 19, 2024 · 9 comments
Closed

how get jni acces? #364

MatejMagat305 opened this issue Mar 19, 2024 · 9 comments

Comments

@MatejMagat305
Copy link

well I try to open my copy libOpenCL.so in apk (systems libs reject access) and I need location of ..., I try

//go:build android

package openCL

/*
#include <jni.h>
#include <stdlib.h>
#include <string.h>

extern struct android_app *GetAndroidApp();
const char* GetNativeLibraryDir() {
    const char* result = NULL;
    struct android_app* app = GetAndroidApp();
    if (!app) {
        goto cleanup;
    }
    JNIEnv* env = app->activity->env;
    jclass contextClass = (*env)->GetObjectClass(env, app->activity->clazz);
    if (!contextClass) {
        goto cleanup;
    }
    jmethodID getApplicationContextMethod = (*env)->GetMethodID(
        env, contextClass, "getApplicationContext", "()Landroid/content/Context;");
    if (!getApplicationContextMethod) {
        goto cleanup;
    }
    jobject contextObject = (*env)->CallObjectMethod(env, app->activity->clazz, getApplicationContextMethod);
    if (!contextObject) {
        goto cleanup;
    }
    jmethodID getApplicationInfoMethod = (*env)->GetMethodID(
        env, contextClass, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
    if (!getApplicationInfoMethod) {
        goto cleanup;
    }
    jobject applicationInfoObject = (*env)->CallObjectMethod(
        env, contextObject, getApplicationInfoMethod);
    if (!applicationInfoObject) {
        goto cleanup;
    }
    jfieldID nativeLibraryDirField = (*env)->GetFieldID(
        env, (*env)->GetObjectClass(env, applicationInfoObject),
        "nativeLibraryDir", "Ljava/lang/String;");
    if (!nativeLibraryDirField) {
        goto cleanup;
    }
    jstring nativeLibraryDirString = (*env)->GetObjectField(
        env, applicationInfoObject, nativeLibraryDirField);
    if (!nativeLibraryDirString) {
        goto cleanup;
    }
    const char* nativeLibraryDir = (*env)->GetStringUTFChars(env, nativeLibraryDirString, NULL);
    if (!nativeLibraryDir) {
        goto cleanup;
    }
    result = strdup(nativeLibraryDir);
    (*env)->ReleaseStringUTFChars(env, nativeLibraryDirString, nativeLibraryDir);

cleanup:
    if (contextClass) (*env)->DeleteLocalRef(env, contextClass);
    if (contextObject) (*env)->DeleteLocalRef(env, contextObject);
    if (applicationInfoObject) (*env)->DeleteLocalRef(env, applicationInfoObject);
    if (nativeLibraryDirString) (*env)->DeleteLocalRef(env, nativeLibraryDirString);
    return result;
}
*/
import "C"
import (
	"unsafe"
        ".../purego"
)

func init() {
	cStr := C.GetNativeLibraryDir()
	if uintptr(cStr) != uintptr(0) {
		dir := C.GOString(cStr)
		C.free(unsafe.Pointer(cStr))
		purego.Dlopen(dir+"/libOpenCL")
	}
}

but I have no luck...

please give me advise

@gen2brain
Copy link
Owner

No idea, but it is not related in any way to raylib, sorry. This is not the best place for questions and discussions, it is for issues with raylib-go.

@gen2brain
Copy link
Owner

Why even try to use something like purego on Android, how is it going to find the library there? Does it even support Android? You anyway need C for shared library so why not just use C?

@gen2brain
Copy link
Owner

I just looked at this, and still am not sure what you are trying to do here. JNI is used to access Java from C, of C from Java, you don't even have Java here. You just should use C, i.e. include headers you need, call what you want, and link with that library. How is JNI even related to this?

@MatejMagat305
Copy link
Author

well, sometime I need jni to call something extra ...,

I was able to run my OpenCL purego wrapper on termux(android enviroment), so I would like to try in apk ...

So my question is whether is android_app *GetAndroidApp(); available outside internal library

@gen2brain
Copy link
Owner

You can see for yourself that it is not exposed.
So how is your example related to JNI then? I still don't understand why you even go with all that trouble with purego, just use cgo, link the library, and put the library in android/libs, what do jni and purego have to do with that? There is nothing to gain here, you must use C anyway.

@MatejMagat305
Copy link
Author

so, purego is primary to avoid cgo, but it is also good to avoid complicate link with headers ..., so if I (in my wrapper) create var somename func(...); porego.RegisterFunc(handle, "...", &somename) I do not have to write other version for cgo version, it will work even in cgo (yes, if you have cgo which has good link, it is useless, because cgo is litle bit faster, but if c headers in f.e. in android is coplicate purego still can be usefull)

@gen2brain
Copy link
Owner

But you cannot avoid cgo if you want to compile library as c-shared. You must use it on Android no matter what else you are doing, so how do you avoid cgo?

@gen2brain
Copy link
Owner

In my experience, purego and cgo have exactly the same performance (i.e. I use it for some image decoders). And if I already must use cgo, I just really don't see a point to use experimental library that doesn't even work if function receives or returns a plain struct.

@MatejMagat305
Copy link
Author

well, I was found

func HomeDir() string {

I am NOT trying avoid cgo in android, compile headers to android in Go is hard, so I was try use purego as "cheap wrapper" with many options of paths (androids are very variable with path shared lib) as I have in https://github.com/opencl-pure/pureCL/blob/9bd3c662ac677f6f25beb12282d1e267b5babade/purego_library_unix.go#L25
similar to https://github.com/krrishnarraj/libopencl-stub/blob/4a235674884fcb75886142dd4ce2f9aa08117037/src/libopencl.c#L82 ...

as I notice android libOpenCL.so is not public ..., so I was try copy to internal lib ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants