c++/jvm-jni-starter/jvm-jni-starter.cpp
author František Kučera <franta-hg@frantovo.cz>
Fri, 08 May 2020 00:02:05 +0200
changeset 57 1b21c78d8706
parent 56 813b44590d07
permissions -rw-r--r--
SQLite: demo modul – rozšíření přidávající pár funkcí do SQL
Vzniklo v rámci práce na článku: https://blog.frantovo.cz/c/383/Komplexita%3A%20%C5%99e%C5%A1en%C3%AD%20a%C2%A0prevence
     1 #include <cstdlib>
     2 #include <wchar.h>
     3 #include <locale.h>
     4 #include <string>
     5 
     6 #include <jni.h>
     7 
     8 using namespace std;
     9 
    10 /**
    11  * Spouští JVM z C++, volá statickou metodu ze standardní knihovny (System.currentTimeMillis()) a main() metodu programu SQL-DK
    12  * 
    13  * @param argc
    14  * @param argv
    15  * @return 
    16  */
    17 int main(int argc, char** argv) {
    18 
    19 	setlocale(LC_ALL, "");
    20 
    21 	JavaVM *jvm;
    22 	JNIEnv *env;
    23 
    24 	JavaVMOption options[1];
    25 	char * home = getenv("HOME");
    26 
    27 	string classPath;
    28 	classPath.append("-Djava.class.path=");
    29 	classPath.append(home);
    30 	classPath.append("/projekty/SQL-DK/sql-dk/java/sql-dk/dist/sql-dk.jar");
    31 	classPath.append(":");
    32 	classPath.append(home);
    33 	classPath.append("/projekty/SQL-DK/sql-dk/java/jdbc-loopback-driver/dist/jdbc-loopback-driver.jar");
    34 
    35 	wprintf(L"classPath: %s\n", classPath.c_str());
    36 
    37 	options[0].optionString = new char[classPath.length() + 1];
    38 	copy(classPath.begin(), classPath.end(), options[0].optionString);
    39 
    40 	JavaVMInitArgs vm_args;
    41 	vm_args.version = JNI_VERSION_1_8;
    42 	vm_args.nOptions = 1;
    43 	vm_args.options = options;
    44 	vm_args.ignoreUnrecognized = false;
    45 
    46 	JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args);
    47 
    48 	string className = "java/lang/System";
    49 
    50 	jclass cls = env->FindClass(className.c_str());
    51 	if (cls) {
    52 		string methodName = "currentTimeMillis";
    53 		jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), "()J");
    54 
    55 		if (mid) {
    56 			jlong time = env->CallStaticLongMethod(cls, mid);
    57 			wprintf(L"Aktuální čas Javy: %d\n", time);
    58 
    59 		} else {
    60 			wprintf(L"Metoda nebyla nalezena: %s\n", methodName.c_str());
    61 		}
    62 	} else {
    63 		wprintf(L"Třída nebyla nalezena: %s\n", className.c_str());
    64 	}
    65 
    66 	delete cls; // TODO: jak čistit?
    67 
    68 	className = "info/globalcode/sql/dk/CLIStarter";
    69 	cls = env->FindClass(className.c_str());
    70 	if (cls) {
    71 		string methodName = "main";
    72 		jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), "([Ljava/lang/String;)V");
    73 
    74 		if (mid) {
    75 			//jstring arg = env->NewStringUTF("--list-databases");
    76 			//jarray args = env->NewObjectArray(1, env->FindClass("java/lang/String"), arg);
    77 
    78 			jobjectArray args = env->NewObjectArray(10, env->FindClass("java/lang/String"), NULL);
    79 			int a = 0;
    80 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("--db"));
    81 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("loopback"));
    82 			//env->SetObjectArrayElement(args, a++, env->NewStringUTF("--sql-in")); // vyžaduje (libovolná) data na standardním vstupu
    83 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("--sql"));
    84 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("…"));
    85 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("--data"));
    86 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("2"));
    87 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("a"));
    88 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("b"));
    89 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("c"));
    90 			env->SetObjectArrayElement(args, a++, env->NewStringUTF("d"));
    91 
    92 
    93 			for (int i = 0; i < 10; i++) {
    94 				env->CallStaticVoidMethod(cls, mid, args);
    95 				// FIXME: nefuguje – JVM ukončí proces → vlákna/procesy
    96 			}
    97 
    98 
    99 		} else {
   100 			wprintf(L"Metoda nebyla nalezena: %s\n", methodName.c_str());
   101 		}
   102 	} else {
   103 		wprintf(L"Třída nebyla nalezena: %s\n", className.c_str());
   104 	}
   105 
   106 	jvm->DestroyJavaVM();
   107 	return 0;
   108 }
   109