Move some native codes to there

This commit is contained in:
khanhduytran0 committed 2020-09-04 15:27:56 +07:00
1 parent 97893a2222
commit 2f0f4f8ee6
13 files changed
+568 -15

No files matched your search

+10
View File
@@ -15,6 +15,10 @@ android {
versionCode 156235
versionName "3.2.0_6401b_20200822"
multiDexEnabled true //important
ndk {
abiFilters "armeabi-v7a"
}
}
buildTypes {
@@ -28,6 +32,12 @@ android {
}
}
externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
}
}
// Keep the following configuration in order to might make Minecraft 1.12 support.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Binary file not shown.
@@ -28,7 +28,7 @@ public class InstallModActivity extends AppCompatActivity
Surface surface = new Surface(tex);
Field field = surface.getClass().getDeclaredField("mNativeObject");
field.setAccessible(true);
BinaryExecutor.setupBridgeSurfaceAWT((long) field.get(surface));
JREUtils.setupBridgeSurfaceAWT((long) field.get(surface));
} catch (Throwable th) {
Tools.showError(InstallModActivity.this, th, true);
}
@@ -97,12 +97,12 @@ public class InstallModActivity extends AppCompatActivity
System.out.println(Arrays.toString(javaArgList.toArray(new String[0])));
BinaryExecutor.setJavaEnvironment(this);
JREUtils.setJavaEnvironment(this);
BinaryExecutor.redirectStdio();
BinaryExecutor.setJavaEnvironment(this);
BinaryExecutor.initJavaRuntime();
BinaryExecutor.chdir(Tools.MAIN_PATH);
JREUtils.redirectStdio();
JREUtils.setJavaEnvironment(this);
JREUtils.initJavaRuntime();
JREUtils.chdir(Tools.MAIN_PATH);
VMLauncher.launchJVM(javaArgList.toArray(new String[0]));
} catch (Throwable th) {
@@ -4,10 +4,9 @@ import android.system.*;
import java.io.*;
import android.content.*;
// This class should be named as 'LoadMe' as original
public class BinaryExecutor
public class JREUtils
{
private BinaryExecutor() {}
private JREUtils() {}
public static void initJavaRuntime() {
dlopen(Tools.homeJreDir + "/lib/jli/libjli.so");
@@ -79,6 +78,6 @@ public class BinaryExecutor
public static native int executeBinary(String[] args);
static {
System.loadLibrary("binexecutor");
System.loadLibrary("pojavexec");
}
}
@@ -643,7 +643,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
if (!isCalled) {
isCalled = true;
BinaryExecutor.setupBridgeWindow(new Surface(texture));
JREUtils.setupBridgeWindow(new Surface(texture));
new Thread(new Runnable(){
@@ -1027,7 +1027,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
// can fix java?
// setEnvironment("ORIGIN", Tools.homeJreDir + "/lib");
BinaryExecutor.setJavaEnvironment(this);
JREUtils.setJavaEnvironment(this);
if (LAUNCH_TYPE == LTYPE_PROCESS) {
mLaunchShell.writeToProcess("cd $HOME");
@@ -1044,7 +1044,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
Os.dup2(FileDescriptor.out, OsConstants.STDOUT_FILENO);
*/
BinaryExecutor.redirectStdio();
JREUtils.redirectStdio();
// DEPRECATED constructor (String) api 29
/*
FileObserver fobs = new FileObserver(logFile.getAbsolutePath(), FileObserver.MODIFY){
@@ -1071,8 +1071,8 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
}
}, "RuntimeLogThread").start();
BinaryExecutor.initJavaRuntime();
BinaryExecutor.chdir(Tools.MAIN_PATH);
JREUtils.initJavaRuntime();
JREUtils.chdir(Tools.MAIN_PATH);
if (new File(Tools.MAIN_PATH, "strace.txt").exists()) {
startStrace(android.os.Process.myTid());
+13
View File
@@ -0,0 +1,13 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -ldl -llog -lEGL -landroid
LOCAL_MODULE := pojavexec
LOCAL_SRC_FILES := \
egl_bridge.c \
jre_launcher.c \
utils.c
include $(BUILD_SHARED_LIBRARY)
+5
View File
@@ -0,0 +1,5 @@
# NDK_TOOLCHAIN_VERSION := 4.9
APP_PLATFORM := android-21
APP_STL := system
APP_ABI := armeabi-v7a x86
# arm64-v8a x86_64
+129
View File
@@ -0,0 +1,129 @@
#include <jni.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <EGL/egl.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
struct ANativeWindow* windowBridge;
struct PotatoBridge {
void* eglContext;
void* eglDisplay;
void* eglSurface;
/*
void* eglSurfaceRead;
void* eglSurfaceDraw;
*/
};
struct PotatoBridge potatoBridge;
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_JREUtils_setupBridgeWindow(JNIEnv* env, jclass clazz, jobject surface) {
windowBridge = ANativeWindow_fromSurface(env, surface);
}
// Called from JNI_OnLoad of liblwjgl_opengl32
void pojav_openGLOnLoad() {
printf("ANativeWindow pointer = %p\n", windowBridge);
potatoBridge.eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (potatoBridge.eglDisplay == EGL_NO_DISPLAY) {
printf("Error: eglGetDefaultDisplay() failed: %p\n", eglGetError());
return; // -1;
}
eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglInitialize(potatoBridge.eglDisplay, NULL, NULL)) {
printf("Error: eglInitialize() failed\n");
return; // -2;
}
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
static const EGLint ctx_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLConfig config;
EGLint num_configs;
EGLint vid;
if (!eglChooseConfig(potatoBridge.eglDisplay, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
return; // -3;
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(potatoBridge.eglDisplay, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
return; // -4;
}
eglBindAPI(EGL_OPENGL_ES_API);
potatoBridge.eglContext = eglCreateContext(potatoBridge.eglDisplay, config, EGL_NO_CONTEXT, ctx_attribs);
if (!potatoBridge.eglContext) {
printf("Error: eglCreateContext failed\n");
return; // -5;
}
// test eglQueryContext()
{
EGLint val;
eglQueryContext(potatoBridge.eglDisplay, potatoBridge.eglContext, EGL_CONTEXT_CLIENT_VERSION, &val);
assert(val == 2);
}
potatoBridge.eglSurface = eglCreateWindowSurface(potatoBridge.eglDisplay, config, windowBridge, NULL);
if (!potatoBridge.eglSurface) {
printf("Error: eglCreateWindowSurface failed: %p\n", eglGetError());
return; // -6;
}
// sanity checks
{
EGLint val;
assert(eglGetConfigAttrib(potatoBridge.eglDisplay, config, EGL_SURFACE_TYPE, &val));
assert(val & EGL_WINDOW_BIT);
}
printf("EGLContext=%p, EGLDisplay=%p, EGLSurface=%p\n",
potatoBridge.eglContext,
potatoBridge.eglDisplay,
potatoBridge.eglSurface
);
if (eglMakeCurrent(potatoBridge.eglDisplay, potatoBridge.eglSurface, potatoBridge.eglSurface, potatoBridge.eglContext) == EGL_FALSE) {
printf("Error: eglMakeCurrent() failed: %p\n", eglGetError());
}
}
void pojav_openGLOnUnload() {
eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(potatoBridge.eglDisplay, potatoBridge.eglSurface);
eglDestroyContext(potatoBridge.eglDisplay, potatoBridge.eglContext);
eglTerminate(potatoBridge.eglDisplay);
eglReleaseThread();
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglSwapBuffers(JNIEnv *env, jclass clazz) {
return eglSwapBuffers(potatoBridge.eglDisplay, potatoBridge.eglSurface);
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglSwapInterval(JNIEnv *env, jclass clazz, jint interval) {
return eglSwapInterval(potatoBridge.eglDisplay, interval);
}
+200
View File
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>
#include <android/log.h>
#include <dlfcn.h>
// Boardwalk: missing include
#include <string.h>
#include "log.h"
#include "utils.h"
// PojavLancher: fixme: are these wrong?
#define FULL_VERSION "1.9.0-internal"
#define DOT_VERSION "1.9"
typedef jint JNI_CreateJavaVM_func(JavaVM **pvm, void **penv, void *args);
typedef jint JLI_Launch_func(int argc, char ** argv, /* main argc, argc */
int jargc, const char** jargv, /* java args */
int appclassc, const char** appclassv, /* app classpath */
const char* fullversion, /* full version defined */
const char* dotversion, /* dot version defined */
const char* pname, /* program name */
const char* lname, /* launcher name */
jboolean javaargs, /* JAVA_ARGS */
jboolean cpwildcard, /* classpath wildcard*/
jboolean javaw, /* windows-only javaw */
jint ergo /* ergonomics class policy */
);
JavaVM *runtimeJavaVMPtr = NULL;;
JNIEnv *runtimeJNIEnvPtr = NULL;
JavaVM *dalvikJavaVMPtr = NULL;
JNIEnv *dalvikJNIEnvPtr = NULL;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
if (dalvikJavaVMPtr == NULL) {
//Save dalvik global JavaVM pointer
dalvikJavaVMPtr = vm;
LOGD("JNI_OnLoad calling GetEnv()");
JNIEnv* env = NULL;
(*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4);
/* Boardwalk: not used
LOGD("JNI_OnLoad calling initDalvikProxySelectorData()");
initDalvikProxySelectorData(env);
*/
}
LOGD("JNI_OnLoad returning()");
return JNI_VERSION_1_4;
}
static void logArgs(int argc, char** argv) {
/* BlockLauncher: disable logging
int i;
for (i = 0; i < argc; i++) {
LOGD("arg[%d]: %s", i, argv[i]);
}
*/
}
JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_createLaunchMainJVM(JNIEnv *env, jclass clazz, jobjectArray vmArgArr, jstring mainClassStr, jobjectArray mainArgArr) {
void *libjvm = dlopen("libjvm.so", RTLD_NOW + RTLD_GLOBAL);
if (libjvm == NULL) {
LOGE("dlopen failed to open libjvm.so (dlerror %s).", dlerror());
return -1;
}
JNI_CreateJavaVM_func *jl_JNI_CreateJavaVM = (JNI_CreateJavaVM_func *) dlsym(libjvm, "JNI_CreateJavaVM");
if (jl_JNI_CreateJavaVM == NULL) {
LOGE("dlsym failed to get JNI_CreateJavaVM (dlerror %s).", dlerror());
return -1;
}
int vm_argc = (*env)->GetArrayLength(env, vmArgArr);
char **vm_argv = convert_to_char_array(env, vmArgArr);
int main_argc = (*env)->GetArrayLength(env, mainArgArr);
char **main_argv = convert_to_char_array(env, mainArgArr);
JavaVMInitArgs vm_args;
JavaVMOption options[vm_argc];
for (int i = 0; i < vm_argc; i++) {
options[i].optionString = vm_argv[i];
}
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = vm_argc;
vm_args.ignoreUnrecognized = JNI_FALSE;
jint res = (jint) jl_JNI_CreateJavaVM(&runtimeJavaVMPtr, (void**)&runtimeJNIEnvPtr, &vm_args);
// delete options;
char *main_class_c = (*env)->GetStringUTFChars(env, mainClassStr, 0);
jclass mainClass = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, main_class_c);
jmethodID mainMethod = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, mainClass, "main", "([Ljava/lang/String;)V");
// Need recreate jobjectArray to make JNIEnv is 'runtimeJNIEnvPtr'.
jobjectArray runtime_main_argv = convert_from_char_array(runtimeJNIEnvPtr, main_argv, main_argc);
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(runtimeJNIEnvPtr, mainClass, mainMethod, runtime_main_argv);
(*env)->ReleaseStringUTFChars(env, mainClassStr, main_class_c);
free_char_array(env, mainArgArr, main_argv);
free_char_array(env, vmArgArr, vm_argv);
return res;
}
static jint launchJVM(int argc, char** argv) {
logArgs(argc, argv);
void* libjli = dlopen("libjli.so", RTLD_LAZY | RTLD_GLOBAL);
// Boardwalk: silence
// LOGD("JLI lib = %x", (int)libjli);
if (NULL == libjli) {
LOGE("JLI lib = NULL: %s", dlerror());
return 0;
}
LOGD("Found JLI lib");
JLI_Launch_func *pJLI_Launch =
(JLI_Launch_func *)dlsym(libjli, "JLI_Launch");
// Boardwalk: silence
// LOGD("JLI_Launch = 0x%x", *(int*)&pJLI_Launch);
if (NULL == pJLI_Launch) {
LOGE("JLI_Launch = NULL");
return 0;
}
LOGD("Calling JLI_Launch");
return pJLI_Launch(argc, argv,
0, NULL, 0, NULL, FULL_VERSION,
DOT_VERSION, *argv, *argv, /* "java", "openjdk", */
JNI_FALSE, JNI_TRUE, JNI_FALSE, 0);
}
/*
* Class: com_oracle_embedded_launcher_VMLauncher
* Method: launchJVM
* Signature: ([Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_launchJVM(JNIEnv *env, jclass clazz, jobjectArray argsArray) {
jint res = 0;
// int i;
// Save dalvik JNIEnv pointer for JVM launch thread
dalvikJNIEnvPtr = env;
if (argsArray == NULL) {
LOGE("Args array null, returning");
//handle error
return 0;
}
int argc = (*env)->GetArrayLength(env, argsArray);
char **argv = convert_to_char_array(env, argsArray);
LOGD("Done processing args");
res = launchJVM(argc, argv);
LOGD("Freeing args");
free_char_array(env, argsArray, argv);
LOGD("Free done");
return res;
}
+26
View File
@@ -0,0 +1,26 @@
#ifdef __ANDROID__
#include <android/log.h>
#define TAG "LaunchJVM"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __ANDROID__
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#else
#define LOGE(...) printf(__VA_ARGS__)
#define LOGW(...) printf(__VA_ARGS__)
#define LOGI(...) printf(__VA_ARGS__)
#define LOGD(...) printf(__VA_ARGS__)
#endif
#ifdef __cplusplus
}
#endif
+162
View File
@@ -0,0 +1,162 @@
#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**);
typedef void (*android_update_LD_LIBRARY_PATH_t)(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 * 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);
}
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_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_JREUtils_setLdLibraryPath(JNIEnv *env, jclass clazz, jstring ldLibraryPath) {
// jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
android_update_LD_LIBRARY_PATH_t android_update_LD_LIBRARY_PATH;
void *libdl_handle = dlopen("libdl.so", RTLD_LAZY);
void *updateLdLibPath = dlsym(libdl_handle, "android_update_LD_LIBRARY_PATH");
if (updateLdLibPath == NULL) {
updateLdLibPath = dlsym(libdl_handle, "__loader_android_update_LD_LIBRARY_PATH");
if (updateLdLibPath == NULL) {
char *dl_error_c = dlerror();
LOGE("Error getting symbol android_update_LD_LIBRARY_PATH: %s", dl_error_c);
// (*env)->ThrowNew(env, exception_cls, dl_error_c);
}
}
android_update_LD_LIBRARY_PATH = (android_update_LD_LIBRARY_PATH_t) updateLdLibPath;
const char* ldLibPathUtf = (*env)->GetStringUTFChars(env, ldLibraryPath, 0);
android_update_LD_LIBRARY_PATH(ldLibPathUtf);
(*env)->ReleaseStringUTFChars(env, ldLibraryPath, ldLibPathUtf);
}
JNIEXPORT jboolean JNICALL Java_net_kdt_pojavlaunch_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) {
LOGE("dlopen %s failed: %s", nameUtf, dlerror());
} else {
LOGD("dlopen %s success", nameUtf);
}
(*env)->ReleaseStringUTFChars(env, name, nameUtf);
return handle != NULL;
}
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_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_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_JREUtils_executeForkedBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
int x, status;
x = fork();
if (x > 0) {
wait(&status);
} else {
execvpe();
}
return status;
}
*/
+9
View File
@@ -0,0 +1,9 @@
#ifndef _BINARY_UTILS_H_
#define _BINARY_UTILS_H_
char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray);
jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows);
void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charArray);
#endif // _BINARY_UTILS_H_
Binary file not shown.