【问题标题】:JNI Java from C++ ; Print to output?来自 C++ 的 JNI Java;打印输出?
【发布时间】:2013-10-23 17:09:49
【问题描述】:

我正在使用 JNI 在 C++ 程序中调用一些 Java 代码。我需要将一些文本从 Java 打印到 C++ 标准输出。

我该怎么做?

我尝试:System.out.println("sdf"); 在 java 中,没有出现。

请帮忙:D

【问题讨论】:

    标签: java c++ java-native-interface stdout


    【解决方案1】:
    public class Natives {
        public static native void printf(final String WhatToPrintHere);
    }
    
    public class Main {
        public static void main(String args[]) {
            Natives.printf("Testing printing from Java");
        }
    }
    
    
    extern "C" JNIEXPORT void Java_Natives_printf(JNIEnv* env, jobject obj, jstring WhatToPrintHere)
    {
        const char* Str = env->GetStringUTFChars(WhatToPrintHere, 0);
    
        std::cout<< Str <<"\n";
    
        env->ReleaseStringUTFChars(WhatToPrintHere, Str);
    }
    

    【讨论】:

    • 这使代码有几个假设: 1) Unicode 是所需的字符集,而 UTF-8 是所需的编码。 2) cout 不会因GetStringUTFChars 产生的非标准修改的UTF-8 编码 而窒息。它可以处理可能字符串的子集,但它不检查也不记录它。
    【解决方案2】:

    您可以尝试像这样通过 JNI 调用 printf:(来自 wiki

    JNIEXPORT void JNICALL Java_ClassName_MethodName
            (JNIEnv *env, jobject obj, jstring javaString) {
        // printf("%s", javaString);        // INCORRECT: Could crash VM!
    
        // Correct way: Create and release native string from Java string
        const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0);
        printf("%s", nativeString);
        (*env)->ReleaseStringUTFChars(env, javaString, nativeString);
    }
    

    【讨论】:

      【解决方案3】:

      由于您没有指定字符集和编码,本机方法应该处理 Java 确定为平台默认值的内容。否则,“You win 100€”不会像“You win 100á,¬”那样打印出来只是巧合

      所以,声明如下:

          public static native void println(final byte[] stringBytes);
      

      这样称呼:

          Natives.println("You win 100€".getBytes()); // platforms default character set/encoding
      

      并像这样实现它:

      extern "C" JNIEXPORT void JNICALL Java_Natives_println(JNIEnv *env, jclass, jbyteArray stringBytes)
      {
          auto bytes  = (env->GetByteArrayElements(stringBytes, 0)); // is_copy is not used
          auto str = reinterpret_cast<const char *>(bytes);
          std::cout << str << std::endl;
          env->ReleaseByteArrayElements(stringBytes, bytes, JNI_ABORT);  // no need to copy back
      }
      

      如果您确实知道所需的特定字符集/编码(又称“代码页”),则可以将 Charset 传递给 String.getBytes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-09
        • 1970-01-01
        • 1970-01-01
        • 2013-12-28
        • 1970-01-01
        • 2015-03-16
        相关资源
        最近更新 更多