代码之家  ›  专栏  ›  技术社区  ›  Ayusman

jstring到l_tchar*格式

  •  1
  • Ayusman  · 技术社区  · 15 年前

    我一直试图调用一个具有以下签名的C函数

    int changeFoo(L_TCHAR* pszFileSrc){....}
    

    在我的jni调用中,我的方法如下所示:

    JNIEXPORT jint JNICALL Java_com_me_L_AFoo(JNIEnv * env, jclass jclass, jstring pSrc)
    {
        jint retValue = -100;
        retValue = changeFoo(pSrc);
        return retValue;
    }
    

    我在visual studio中得到以下错误。

    错误1错误C2664:“l_fileconvert”:无法将参数1从“jstring”转换为“l_tchar*”C:\ayusman\work\myvcpp\ltexampledll\ltexampledll\ltexamplemain.cpp 46 ltexampledll

    当我看到l_tchar的定义时*

    以下是我在头文件中得到的信息(按顺序):

    typedef TCHAR L_TCHAR;
    typedef WCHAR TCHAR,*PTCHAR;
    typedef wchar_t WCHAR; //wc, 16 bit UNICODE char
    

    我在Java上工作,这是我正在尝试构建的JNI应用程序。 有人能帮我把这个转换成什么吗?

    1 回复  |  直到 15 年前
        1
  •  2
  •   Sarah Roberts    15 年前

    必须手动转换字符串。下面是一些(更正的)示例代码:

    #include <stdio.h>
    #include <wchar.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    
    #include "Foo.h"
    #define SURROGATE_MASK 0xD800
    #define is_surrogate(c) (((c) & SURROGATE_MASK) == SURROGATE_MASK)
    
    static wchar_t calculate_code_point(wchar_t surrogate_1, wchar_t surrogate_2);
    
    JNIEXPORT void JNICALL
    Java_Foo_foo(JNIEnv *env, jobject obj, jstring bar) {
      const jchar *chars = NULL;
      wchar_t *result = NULL;
      size_t len;
      size_t source_pos, result_pos;
    
      if (bar == NULL) {
        return;
      }
    
      len = (*env)->GetStringLength(env, bar);
      chars = (*env)->GetStringChars(env, bar, NULL);
      if (chars == NULL) {
        return;
      }
    
      result = (wchar_t *) malloc(sizeof(wchar_t) * (len + 1));
      source_pos = result_pos = 0;
      while (source_pos < len) {
        wchar_t curr_char = chars[source_pos++];
        if (is_surrogate(curr_char)) {
          wchar_t surrogate_1 = curr_char;
          wchar_t surrogate_2 = chars[source_pos++];
          curr_char = calculate_code_point(surrogate_1, surrogate_2);
        }
        result[result_pos++] = curr_char;
      }
      result[result_pos] = L'\0';
    
      (*env)->ReleaseStringChars(env, bar, chars);
    
      printf("%ls\n", result);
      free(result);
    }
    
    /**
     * Based on example code from http://unicode.org/faq/utf_bom.hmtl
     */
    static wchar_t calculate_code_point(wchar_t high_surrogate, wchar_t low_surrogate) {
      wchar_t x = (high_surrogate & ((1 << 6) - 1)) <<10 | low_surrogate & ((1 << 10) - 1);
      wchar_t w = (high_surrogate >> 6) & ((1 << 5) - 1);
      wchar_t u = w + 1;
      return u << 16 | x;
    }
    

    请注意,此代码仅适用于使用Java 5或以上,并且您的WHARGYT数据类型为四字节长。如果您使用的是Java 1.4或以下,或者您的WHARGHETT数据类型是两个字节长,那么就不必担心代理。

    这段代码还省略了一些基本的错误检查,并假定两个代理中的第一个代理项是高阶代理项(在我的机器上就是这种情况)。您可以通过它们各自的值来确定哪个代理项是高阶代理项,哪个是低阶代理项。高阶代理项介于0xd800和0xdbff之间(包括0xd800和0xdbff)。低阶代理项介于0xdc00和0xdfff之间(包括0xdc00和0xdfff)。如果发现高阶代理项未与低阶代理项配对,或者低阶代理项未与高阶代理项配对,则字符串编码不正确。