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