149 lines
4.8 KiB
C
149 lines
4.8 KiB
C
#include "jni.h"
|
|
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include "log.h"
|
|
|
|
#include "utils.h"
|
|
|
|
typedef int (*Main_Function_t)(int, char**);
|
|
|
|
long shared_awt_surface;
|
|
|
|
char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray) {
|
|
int num_rows = (*env)->GetArrayLength(env, jstringArray);
|
|
char **cArray = (char **) malloc((num_rows + 1) * sizeof(char*));
|
|
jstring row;
|
|
|
|
for (int i = 0; i < num_rows; i++) {
|
|
row = (jstring) (*env)->GetObjectArrayElement(env, jstringArray, i);
|
|
cArray[i] = (char*)(*env)->GetStringUTFChars(env, row, 0);
|
|
}
|
|
cArray[num_rows] = NULL;
|
|
|
|
return cArray;
|
|
}
|
|
|
|
jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows) {
|
|
jobjectArray resultArr = (*env)->NewObjectArray(env, num_rows, (*env)->FindClass(env, "java/lang/String"), NULL);
|
|
jstring row;
|
|
|
|
for (int i = 0; i < num_rows; i++) {
|
|
row = (jstring) (*env)->NewStringUTF(env, charArray[i]);
|
|
(*env)->SetObjectArrayElement(env, resultArr, i, row);
|
|
}
|
|
|
|
return resultArr;
|
|
}
|
|
|
|
void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charArray) {
|
|
int num_rows = (*env)->GetArrayLength(env, jstringArray);
|
|
jstring row;
|
|
|
|
for (int i = 0; i < num_rows; i++) {
|
|
row = (jstring) (*env)->GetObjectArrayElement(env, jstringArray, i);
|
|
(*env)->ReleaseStringUTFChars(env, row, charArray[i]);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupBridgeSurfaceAWT(JNIEnv *env, jclass clazz, jlong surface) {
|
|
shared_awt_surface = surface;
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_android_view_Surface_nativeGetBridgeSurfaceAWT(JNIEnv *env, jclass clazz) {
|
|
return (jlong) shared_awt_surface;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_android_os_OpenJDKNativeRegister_nativeRegisterNatives(JNIEnv *env, jclass clazz, jstring registerSymbol) {
|
|
const char *register_symbol_c = (*env)->GetStringUTFChars(env, registerSymbol, 0);
|
|
void *symbol = dlsym(RTLD_DEFAULT, register_symbol_c);
|
|
if (symbol == NULL) {
|
|
printf("dlsym %s failed: %s\n", register_symbol_c, dlerror());
|
|
return -1;
|
|
}
|
|
|
|
int (*registerNativesForClass)(JNIEnv*) = symbol;
|
|
int result = registerNativesForClass(env);
|
|
(*env)->ReleaseStringUTFChars(env, registerSymbol, register_symbol_c);
|
|
|
|
return (jint) result;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setLdLibraryPath(JNIEnv *env, jclass clazz, jstring ldLibraryPath) {
|
|
// jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
|
|
|
|
const char* ldLibPathUtf = (*env)->GetStringUTFChars(env, ldLibraryPath, 0);
|
|
setenv("LD_LIBRARY_PATH", ldLibPathUtf, 1);
|
|
(*env)->ReleaseStringUTFChars(env, ldLibraryPath, ldLibPathUtf);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_dlopen(JNIEnv *env, jclass clazz, jstring name) {
|
|
const char *nameUtf = (*env)->GetStringUTFChars(env, name, 0);
|
|
void* handle = dlopen(nameUtf, RTLD_GLOBAL | RTLD_LAZY);
|
|
if (!handle) {
|
|
printf("dlopen %s failed: %s\n", nameUtf, dlerror());
|
|
} else {
|
|
printf("dlopen %s success\n", nameUtf);
|
|
}
|
|
(*env)->ReleaseStringUTFChars(env, name, nameUtf);
|
|
return handle != NULL;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_chdir(JNIEnv *env, jclass clazz, jstring nameStr) {
|
|
const char *name = (*env)->GetStringUTFChars(env, nameStr, NULL);
|
|
int retval = chdir(name);
|
|
(*env)->ReleaseStringUTFChars(env, nameStr, name);
|
|
return retval;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_executeBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
|
|
jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
|
|
jstring execFile = (*env)->GetObjectArrayElement(env, cmdArgs, 0);
|
|
|
|
char *exec_file_c = (char*) (*env)->GetStringUTFChars(env, execFile, 0);
|
|
void *exec_binary_handle = dlopen(exec_file_c, RTLD_LAZY);
|
|
|
|
// (*env)->ReleaseStringUTFChars(env, ldLibraryPath, ld_library_path_c);
|
|
(*env)->ReleaseStringUTFChars(env, execFile, exec_file_c);
|
|
|
|
char *exec_error_c = dlerror();
|
|
if (exec_error_c != NULL) {
|
|
LOGE("Error: %s", exec_error_c);
|
|
(*env)->ThrowNew(env, exception_cls, exec_error_c);
|
|
return -1;
|
|
}
|
|
|
|
Main_Function_t Main_Function;
|
|
Main_Function = (Main_Function_t) dlsym(exec_binary_handle, "main");
|
|
|
|
exec_error_c = dlerror();
|
|
if (exec_error_c != NULL) {
|
|
LOGE("Error: %s", exec_error_c);
|
|
(*env)->ThrowNew(env, exception_cls, exec_error_c);
|
|
return -1;
|
|
}
|
|
|
|
int cmd_argv = (*env)->GetArrayLength(env, cmdArgs);
|
|
char **cmd_args_c = convert_to_char_array(env, cmdArgs);
|
|
int result = Main_Function(cmd_argv, cmd_args_c);
|
|
free_char_array(env, cmdArgs, cmd_args_c);
|
|
return result;
|
|
}
|
|
|
|
// METHOD 2
|
|
/*
|
|
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_executeForkedBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
|
|
int x, status;
|
|
x = fork();
|
|
if (x > 0) {
|
|
wait(&status);
|
|
} else {
|
|
execvpe();
|
|
}
|
|
return status;
|
|
}
|
|
*/
|
|
|