我最终尝试实现的是从 C++ 中启动一个 java 程序,然后使用 JNI 与之交互。
所以我创建了一个简单的测试环境来玩转并学习更多关于 JNI 以及如何使用它的知识。
这是我到目前为止所拥有的:
示例2.java:
public class Sample2 {
JLabel testLabel;
public static boolean booleanMethod(boolean bool) {
return !bool;
}
public Sample2(){
JFrame frame = new JFrame("FrameDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testLabel = new JLabel("test");
testLabel.setPreferredSize(new Dimension(175, 100));
frame.getContentPane().add(testLabel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new Sample2();
}
public void changeLabel(String s){
testLabel.setText(s);
}
}
JNITest.cpp:
int _tmain(int argc, _TCHAR* argv[])
{
JavaVMOption options[3];
static JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass cls, stringClass;
jmethodID mid;
jstring jstr;
jobjectArray args;
jobject obj;
options[0].optionString = "-Djava.class.path=D:\\Studie\\EXP\\Code\\Workspace\\JNItest\\bin"; //2APL\\build"; //Workspace\\JNItest\\bin";
options[1].optionString = "-verbose";
options[2].optionString = "-verbose:jni";
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (status != JNI_ERR) {
cls = env->FindClass("Sample2");
if(cls !=0) {
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if(mid !=0) {
jstr = env->NewStringUTF("-nojade");
stringClass = env->FindClass("java/lang/String");
args = env->NewObjectArray(1, stringClass, jstr);
env->CallStaticVoidMethod(cls, mid, args);
}
现在我接下来要做的是通过调用该changeLabel(String s)
方法来更改框架的标签。
mid = env->GetMethodID(cls, "changeLabel", "(Ljava/lang/String;)V");
jstr = env->NewStringUTF("foobar");
env->CallIntMethod(...?, mid, jstr);
}
jvm->DestroyJavaVM();
return 0;
}
else {
return -1;
}
}
感谢Roger Rowland回答了我之前的问题,我知道env->CallIntMethod(...?, mid, jstr);
需要一个对象才能工作。但实际上已经在main(String[] args)
调用中创建了一个 Sample2 对象的实例,所以我的主要问题是,如何访问public static void main(String[] args)
在 C++ 中以表单创建的对象以将其传递给以env->CallIntMethod(...?, mid, jstr);
更改标签。
免责声明:我删除了一些检查以减少代码的长度,但我仍然可以确保一切都按预期工作,直到env->CallIntMethod(...?, mid, jstr);