我最终尝试实现的是从C ++中启动一个java程序,然后使用JNI与它进行交互。
因此,我创建了一个简单的测试环境,以便了解JNI以及如何使用它。
这是我到目前为止所做的:
Sample2.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回答my previous question我知道env->CallIntMethod(...?, mid, jstr);
需要一个对象才能工作。但实际上已经在main(String[] args)
调用中创建了一个Sample2对象的实例,所以我的主要问题是,如何在C ++中访问以public static void main(String[] args)
形式创建的对象以将其传递给{{ 1}}以便更改标签。
声明:
我删除了一些检查以减少代码的长度,但我可以保证一切都按预期工作,直到env->CallIntMethod(...?, mid, jstr);
答案 0 :(得分:3)
如何访问在public static void main(String [] args)
中创建的对象
没办法。从您的代码中可以清楚地看到本地声明的实例。这就是为什么你需要在java代码中声明静态字段:
static Sample2 instance;
public static void main(String[] args) {
instance = new Sample2();
}
之后,您可以通过
从课程中解析字段instance
fid = (*env)->GetStaticFieldID(
env, cls, "instance", "LSample2;");
或者,如果您的main
非常简单,您可以直接从c ++代码实例化Sample2
- 即使不调用main