在C+中从JNI调用javajar代码+; 我试图在C++语言中模拟这个()代码,以便获得一些数学公式的MaTML转换,但是在最后一个方法调用之后,我的执行被中止 #include <iostream> #include <string.h> #include <jni.h> using namespace std; #define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */ #define USER_CLASSPATH "snuggletex-1.2.2/snuggletex-core-1.2.2.jar" /* where Prog.class is */ #define SNUGGLE_ENGINE "uk/ac/ed/ph/snuggletex/SnuggleEngine" #define SNUGGLE_INPUT "uk/ac/ed/ph/snuggletex/SnuggleInput" #define SNUGGLE_SESSION "uk/ac/ed/ph/snuggletex/SnuggleSession" #define STRING "java/lang/String" JNIEnv *env; JavaVM *jvm; jint res; void initJVM() { #ifdef JNI_VERSION_1_2 JavaVMInitArgs vm_args; JavaVMOption options[1]; options[0].optionString = "-Djava.class.path=" USER_CLASSPATH; vm_args.version = 0x00010002; vm_args.options = options; vm_args.nOptions = 1; vm_args.ignoreUnrecognized = JNI_TRUE; /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); #else JDK1_1InitArgs vm_args; char classpath[1024]; vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs(&vm_args); /* Append USER_CLASSPATH to the default system class path */ sprintf(classpath, "%s%c%s", vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); vm_args.classpath = classpath; /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, &env, &vm_args); #endif /* JNI_VERSION_1_2 */ } void closeJVM() { jvm->DestroyJavaVM(); } jstring JNU_NewStringNative(const char *str) { jstring result; jbyteArray bytes = 0; jclass Cstr; int len; len = strlen(str); bytes = (env)->NewByteArray( len); Cstr = (env)->FindClass(STRING); if (bytes != NULL) { jmethodID mid; (env)->SetByteArrayRegion(bytes, 0, len,(jbyte *)str); mid = env->GetStaticMethodID(Cstr, "<init>", "([B)V"); result = (jstring) (env)->NewObject(Cstr,mid,bytes); (env)->DeleteLocalRef(bytes); return result; } /* else fall through */ return NULL; } int parse_latex(char* input) { jclass engine, Cinput, Csession; jmethodID mid; jstring jstr; jclass stringClass; jobjectArray args; jstring latex = JNU_NewStringNative(input); jstring result; engine = env->FindClass(SNUGGLE_ENGINE); Cinput = env->FindClass(SNUGGLE_INPUT); Csession = env->FindClass(SNUGGLE_SESSION); if (engine==NULL) return -1; mid = env->GetStaticMethodID(engine, "<init>", "()V"); jobject snuggle = env->NewObject(engine, mid); mid = env->GetStaticMethodID(engine, "createSession", "()V"); jobject session = env->NewObject(engine, mid); //if (cls==NULL) return -1; mid = env->GetStaticMethodID(Cinput , "<init>", "(Ljava/lang/String;)V"); jobject input_elem = env->NewObject(Cinput, mid,latex); mid = env->GetStaticMethodID(Csession , "parseInput", "(Luk/ac/ed/ph/snuggletex/SnuggleInput;)V"); env->CallNonvirtualVoidMethod(session, Csession, mid, input_elem); printf("obtaining method\n"); mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;"); printf("calling method\n"); try { result = (jstring)env->CallObjectMethod(session, mid); printf("ok\n"); } catch (...) { jthrowable exc; exc = (env)->ExceptionOccurred(); if (exc) { env->ExceptionDescribe(); //Returns java.lang.NullPointerException } } return 0; } int main() { int resint; initJVM(); resint = parse_latex("$$5^2$$"); closeJVM(); return resint; }

在C+中从JNI调用javajar代码+; 我试图在C++语言中模拟这个()代码,以便获得一些数学公式的MaTML转换,但是在最后一个方法调用之后,我的执行被中止 #include <iostream> #include <string.h> #include <jni.h> using namespace std; #define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */ #define USER_CLASSPATH "snuggletex-1.2.2/snuggletex-core-1.2.2.jar" /* where Prog.class is */ #define SNUGGLE_ENGINE "uk/ac/ed/ph/snuggletex/SnuggleEngine" #define SNUGGLE_INPUT "uk/ac/ed/ph/snuggletex/SnuggleInput" #define SNUGGLE_SESSION "uk/ac/ed/ph/snuggletex/SnuggleSession" #define STRING "java/lang/String" JNIEnv *env; JavaVM *jvm; jint res; void initJVM() { #ifdef JNI_VERSION_1_2 JavaVMInitArgs vm_args; JavaVMOption options[1]; options[0].optionString = "-Djava.class.path=" USER_CLASSPATH; vm_args.version = 0x00010002; vm_args.options = options; vm_args.nOptions = 1; vm_args.ignoreUnrecognized = JNI_TRUE; /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); #else JDK1_1InitArgs vm_args; char classpath[1024]; vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs(&vm_args); /* Append USER_CLASSPATH to the default system class path */ sprintf(classpath, "%s%c%s", vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); vm_args.classpath = classpath; /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, &env, &vm_args); #endif /* JNI_VERSION_1_2 */ } void closeJVM() { jvm->DestroyJavaVM(); } jstring JNU_NewStringNative(const char *str) { jstring result; jbyteArray bytes = 0; jclass Cstr; int len; len = strlen(str); bytes = (env)->NewByteArray( len); Cstr = (env)->FindClass(STRING); if (bytes != NULL) { jmethodID mid; (env)->SetByteArrayRegion(bytes, 0, len,(jbyte *)str); mid = env->GetStaticMethodID(Cstr, "<init>", "([B)V"); result = (jstring) (env)->NewObject(Cstr,mid,bytes); (env)->DeleteLocalRef(bytes); return result; } /* else fall through */ return NULL; } int parse_latex(char* input) { jclass engine, Cinput, Csession; jmethodID mid; jstring jstr; jclass stringClass; jobjectArray args; jstring latex = JNU_NewStringNative(input); jstring result; engine = env->FindClass(SNUGGLE_ENGINE); Cinput = env->FindClass(SNUGGLE_INPUT); Csession = env->FindClass(SNUGGLE_SESSION); if (engine==NULL) return -1; mid = env->GetStaticMethodID(engine, "<init>", "()V"); jobject snuggle = env->NewObject(engine, mid); mid = env->GetStaticMethodID(engine, "createSession", "()V"); jobject session = env->NewObject(engine, mid); //if (cls==NULL) return -1; mid = env->GetStaticMethodID(Cinput , "<init>", "(Ljava/lang/String;)V"); jobject input_elem = env->NewObject(Cinput, mid,latex); mid = env->GetStaticMethodID(Csession , "parseInput", "(Luk/ac/ed/ph/snuggletex/SnuggleInput;)V"); env->CallNonvirtualVoidMethod(session, Csession, mid, input_elem); printf("obtaining method\n"); mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;"); printf("calling method\n"); try { result = (jstring)env->CallObjectMethod(session, mid); printf("ok\n"); } catch (...) { jthrowable exc; exc = (env)->ExceptionOccurred(); if (exc) { env->ExceptionDescribe(); //Returns java.lang.NullPointerException } } return 0; } int main() { int resint; initJVM(); resint = parse_latex("$$5^2$$"); closeJVM(); return resint; },java,c++,java-native-interface,latex,mathml,Java,C++,Java Native Interface,Latex,Mathml,我错在哪里?提前谢谢 编辑 在我看来,env->CallObjectMethod(session,mid)//中止的抛出C++异常, 尤其是java.lang.NullPointerException 解决方案 #include <iostream> #include <string.h> #include <jni.h> #include <stdlib.h> using namespace std; #define PATH_SEPARAT

我错在哪里?提前谢谢

编辑

在我看来,
env->CallObjectMethod(session,mid)//中止的抛出C++异常,
尤其是
java.lang.NullPointerException

解决方案

#include <iostream>
#include <string.h>
#include <jni.h>
#include <stdlib.h>

using namespace std;

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */
#define USER_CLASSPATH "snuggletex-1.2.2/snuggletex-core-1.2.2.jar" /* where Prog.class is */

#define SNUGGLE_ENGINE  "uk/ac/ed/ph/snuggletex/SnuggleEngine"
#define SNUGGLE_INPUT   "uk/ac/ed/ph/snuggletex/SnuggleInput"
#define SNUGGLE_SESSION "uk/ac/ed/ph/snuggletex/SnuggleSession"
#define STRING          "java/lang/String"

JNIEnv *env;
 JavaVM *jvm;
 jint res;

void initJVM() {

#ifdef JNI_VERSION_1_2
 JavaVMInitArgs vm_args;
 JavaVMOption options[1];
 options[0].optionString =
 "-Djava.class.path=" USER_CLASSPATH;
 vm_args.version = 0x00010002;
 vm_args.options = options;
 vm_args.nOptions = 1;
 vm_args.ignoreUnrecognized = JNI_TRUE;
 /* Create the Java VM */
 res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
#else
 JDK1_1InitArgs vm_args;
 char classpath[1024];
 vm_args.version = 0x00010001;
 JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the default system class path */
 sprintf(classpath, "%s%c%s",
vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
 vm_args.classpath = classpath;
 /* Create the Java VM */
 res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
#endif /* JNI_VERSION_1_2 */


}

void closeJVM() {
    jvm->DestroyJavaVM();
}


jstring JNU_NewStringNative(const char *str)
{
 jclass strClass = env->FindClass("java/lang/String"); 
 jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); 
 jstring encoding = env->NewStringUTF("GBK"); 

jbyteArray bytes = env->NewByteArray(strlen(str)); 
env->SetByteArrayRegion(bytes, 0, strlen(str), (jbyte*)str); 
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}


const char * parse_latex(char* input) {

    jclass engine, Cinput, Csession;
    jmethodID mid;
    jstring jstr;
    jclass stringClass;
    jobjectArray args;
    jstring latex = JNU_NewStringNative(input);
    jstring result;



    engine = env->FindClass(SNUGGLE_ENGINE);
    Cinput = env->FindClass(SNUGGLE_INPUT);
    Csession = env->FindClass(SNUGGLE_SESSION);

    // SnuggleEngine engine = new SnuggleEngine();
    mid = env->GetMethodID(engine, "<init>", "()V");
    jobject snuggle = env->NewObject(engine, mid);

    // SnuggleSession session = engine.createSession();
    mid = env->GetMethodID(engine, "createSession", "()L"SNUGGLE_SESSION";");
    jobject session = env->CallObjectMethod(snuggle, mid);

    // SnuggleInput input = new SnuggleInput("$$ x+2=3 $$");
    mid = env->GetMethodID(Cinput , "<init>", "(Ljava/lang/String;)V");
    jobject input_elem = env->NewObject(Cinput, mid, latex);

    // session.parseInput(input);
    mid = env->GetMethodID(Csession , "parseInput", "(L"SNUGGLE_INPUT";)Z");
    env->CallBooleanMethod(session, mid, input_elem);

    // String xmlString = session.buildXMLString();
    mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;");
    result = (jstring) env->CallObjectMethod(session, mid);

    printf("here\n");
    const jbyte *str = (jbyte *)(env)->GetStringUTFChars(result, NULL);

    return ((char*)str);


    return 0;
}



int main() {

    const char* resint;
    initJVM();

    resint = parse_latex("$$ x+2=3 $$");
    if (resint) printf("%s\n", resint); else printf("error\n");

    closeJVM();
    return (resint!=0);

}
#包括
#包括
#包括
#包括
使用名称空间std;
#定义路径_分隔符“;”/*在Solaris上将其定义为“:”*/
#定义用户_类路径“snuggletex-1.2.2/snuggletex-core-1.2.2.jar”/*其中包含Prog.class*/
#将依偎式发动机定义为“uk/ac/ed/ph/依偎式发动机/依偎式发动机”
#定义紧贴输入“uk/ac/ed/ph/snuggletex/SnuggleInput”
#定义“uk/ac/ed/ph/snuggletex/SNUGGLESSESSION”依偎会话
#定义字符串“java/lang/STRING”
JNIEnv*env;
JavaVM*jvm;
金特雷斯;
void initJVM(){
#ifdef JNI_版本1_2
JavaVMInitArgs vm_args;
JavaVMOption选项[1];
选项[0]。选项字符串=
“-Djava.class.path=”用户\类路径;
vm_args.version=0x00010002;
vm_args.options=选项;
vm_args.nOptions=1;
vm_args.ignoreunrecogned=JNI_TRUE;
/*创建JavaVM*/
res=JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
#否则
JDK1_1nitargs vm_args;
字符类路径[1024];
vm_args.version=0x0000001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/*将用户\类路径附加到默认系统类路径*/
sprintf(类路径,“%s%c%s”,
vm_args.classpath、PATH_分隔符、USER_classpath);
vm_args.classpath=类路径;
/*创建JavaVM*/
res=JNI_CreateJavaVM(&jvm,&env,&vm_args);
#endif/*JNI_版本1_2*/
}
void closeJVM(){
jvm->javavm();
}
jstring JNU_newstringative(const char*str)
{
jclass strClass=env->FindClass(“java/lang/String”);
jmethodID=env->GetMethodID(strClass,“,”([BLjava/lang/String;)V”);
jstring encoding=env->NewStringUTF(“GBK”);
jbyteArray bytes=env->NewByteArray(strlen(str));
env->SetByteArrayRegion(字节,0,strlen(str),(jbyte*)str);
return(jstring)env->NewObject(strClass、ctorID、bytes、encoding);
}
常量字符*解析(字符*输入){
jclass引擎,Cinput,Csession;
jmethodidemid;
jstring-jstr;
jclass stringClass;
jobjectArray参数;
jstring latex=JNU_newstringative(输入);
jstring结果;
引擎=环境->FindClass(紧贴引擎);
Cinput=env->FindClass(紧贴输入);
Csession=env->FindClass(依偎会话);
//依偎发动机=新的依偎发动机();
mid=env->GetMethodID(引擎“,”()V”);
jobject-snuggle=env->NewObject(引擎,中间);
//SnuggleSession session=engine.createSession();
mid=env->GetMethodID(引擎,“createSession”和“()L”紧贴会话“;”;
jobject session=env->CallObjectMethod(紧贴,中间);
//紧贴输入=新的紧贴输入($$x+2=3$$);
mid=env->GetMethodID(Cinput,“,”(Ljava/lang/String;)V);
jobject输入\ u elem=env->NewObject(Cinput、mid、latex);
//会话。解析输入(输入);
mid=env->GetMethodID(csSession,“parseInput”,“L”SNUGGLE_INPUT“)Z);
env->CallBooleanMethod(会话、mid、输入元素);
//String xmlString=session.buildXMLString();
mid=env->GetMethodID(Csession,“buildXMLString”,“Ljava/lang/String;”);
结果=(jstring)env->CallObjectMethod(session,mid);
printf(“此处\n”);
常量jbyte*str=(jbyte*)(env)->GetStringUTFChars(结果,NULL);
返回((char*)str);
返回0;
}
int main(){
常量字符*resint;
initJVM();
resint=parse_latex($$x+2=3$$);
if(resint)printf(“%s\n”,resint);else printf(“error\n”);
closeJVM();
返回(resint!=0);
}

您调用了错误的方法

// SnuggleEngine engine = new SnuggleEngine();
mid = env->GetMethodID(engine, "<init>", "()V");
jobject snuggle = env->NewObject(engine, mid);

// SnuggleSession session = engine.createSession();
mid = env->GetMethodID(engine, "createSession", "()L"SNUGGLE_SESSION";");
jobject session = env->CallObjectMethod(snuggle, mid);

// SnuggleInput input = new SnuggleInput("$$ x+2=3 $$");
mid = env->GetMethodID(Cinput , "<init>", "(Ljava/lang/String;)V");
jobject input_elem = env->NewObject(Cinput, mid, latex);

// session.parseInput(input);
mid = env->GetMethodID(Csession , "parseInput", "(L"SNUGGLE_INPUT";)Z");
env->CallBooleanMethod(session, mid, input_elem);

// String xmlString = session.buildXMLString();
mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;");
result = (jstring) env->CallObjectMethod(session, mid);
//SnuggleEngine引擎=新的SnuggleEngine();
mid=env->GetMethodID(引擎“,”()V”);
jobject-snuggle=env->NewObject(引擎,中间);
//SnuggleSession session=engine.createSession();
mid=env->GetMethodID(引擎,“createSession”和“()L”紧贴会话“;”;
jobject session=env->CallObjectMethod(紧贴,中间);
//紧贴输入=新的紧贴输入($$x+2=3$$);
mid=env->GetMethodID(Cinput,“,”(Ljava/lang/String;)V);
jobject输入\ u elem=env->NewObject(Cinput、mid、latex);
//会话。解析输入(输入);
mid=env->GetMethodID(csSession,“parseInput”,“L”SNUGGLE_INPUT“)Z);
env->CallBooleanMethod(会话、mid、输入元素);
//String xmlString=session.buildXMLString();
mid=env->GetMethodID(Csession,“buildXMLString”,“Ljava/lang/String;”);
结果=(jstring)env->CallObjectMethod(session,mid);

我没有测试它。希望它能工作!

在上面给出的链接上:为什么您要无条件地从
JNU\u GetStringNativeChars()返回
NULL
?然后扔掉从API调用中得到的
str
?好吧,谢谢,这只是一些死代码。无论如何,我已经从上面的解决方案中删除了usless代码。谢谢,我不知道你可以指定.jar作为VM类路径。非常感谢!我将在问题中发布完整的更正代码,因为还有一些其他minor问题。
// SnuggleEngine engine = new SnuggleEngine();
mid = env->GetMethodID(engine, "<init>", "()V");
jobject snuggle = env->NewObject(engine, mid);

// SnuggleSession session = engine.createSession();
mid = env->GetMethodID(engine, "createSession", "()L"SNUGGLE_SESSION";");
jobject session = env->CallObjectMethod(snuggle, mid);

// SnuggleInput input = new SnuggleInput("$$ x+2=3 $$");
mid = env->GetMethodID(Cinput , "<init>", "(Ljava/lang/String;)V");
jobject input_elem = env->NewObject(Cinput, mid, latex);

// session.parseInput(input);
mid = env->GetMethodID(Csession , "parseInput", "(L"SNUGGLE_INPUT";)Z");
env->CallBooleanMethod(session, mid, input_elem);

// String xmlString = session.buildXMLString();
mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;");
result = (jstring) env->CallObjectMethod(session, mid);