2013-06-22 2 views
0

У меня есть функция в Java, какЧто вызывать метод, который возвращает char * (String в Java и char * в C++)?

public boolean getIsIn(); 
public String getName(); 

в C++ У меня есть обертку функции, такие как

bool gPGIsIn(){ 
    JNIEnv* env = s3eEdkJNIGetEnv(); 
    return (bool)env->CallBooleanMethod(g_Obj, g_s3eGPGIsIn); 
} 
char* gPGGetName(){ 
    JNIEnv* env = s3eEdkJNIGetEnv(); 
    // below is a problem, what to call 
    //return (char*)env->CallWahtMethod(g_Obj, g_s3eGPGGetName); 
} 

где

static jmethodID g_s3eGPGIsIn = env->GetMethodID(cls, "getIsIn", "()Z"); 
static jmethodID g_s3eGPGGetName = env->GetMethodID(cls, "getName", "()Ljava/lang/String;"); 

Что называть в соответствии с тегами, как проблемы внутри gPGGetName для вызова метода который возвращает char * (String в Java и char * в C++)?

+1

Я ничего о NDK не знаю, но не есть способ, чтобы получить ' std :: string' из этого? Потому что это стандартный тип строки C++. – yzt

+0

Вам нужно дополнительно определить «что» перед «как». Я предполагаю, что 'gPGGetName' - вернуть указатель на первый элемент массива. Какой набор символов и кодирование следует использовать? Должен ли массив каким-то образом прекратиться? Что делать, если кодирование создает то, что похоже на терминатор в середине строки? Как должен распределяться массив и кто должен его освобождать? Если набор символов не поддерживает все символы Юникода в строке, должны ли поддерживаемые символы заменяться символом замещения или быть пропущены или если функция не сработает? –

+0

Назовите все, что вам нравится, это имеет смысл для вас. Не настоящий вопрос. – EJP

ответ

0

Он возвращает String объект, и вы можете использовать JNI string functions преобразовать эту строку в char*:

char* gPGGetName() { 
    jobject objStr = env->CallObjectMethod(g_Obj, g_s3eGPGGetName); 
    jsize len = env->GetStringUTFLength(objStr); 
    const char* strPtr = env->GetStringUTFChars(objStr, 0); 
    char* buffer = (char*)malloc((len + 1) * sizeof(char)); 
    memcpy(buffer, strPtr, len); 
    buffer[len] = '\0'; 
    env->ReleaseStringUTFChars(objStr, strPtr); 
    return buffer; 
} 
+1

Чтобы быть ясным, возвращаемое значение было бы указателем на строку Unicode с завершением 0x00 с измененной кодировкой UTF-8. Если специально для этого не сделано, вызывающий абонент не сможет обработать измененную кодировку UTF-8. (Стандартная кодировка Android - стандартная UTF-8.) Она также может работать, если строка содержит только символы ASCII 1-127 (кодировки идентичны для U + 00001 - U + 0007F), но в вопросе не указано, что ограничение и там есть какой-нибудь код для его проверки. И вызывающий должен освободить строку, вызвав 'free'. –

+0

'* sizeof (char)' не имеет смысла, потому что все задействованные функции используют несколько байтов. Теперь 'sizeof (char)' всегда по определению, независимо от того, сколько бит находится в символе или байте. Поэтому, как вы намереваетесь, 'buffer [len]' всегда будет писать '\ 0' сразу после части, написанной 'memcpy'. –

+0

@TomBlodget Я знаю, что '* sizeof (char)' избыточен, но в любом случае он будет оптимизирован, а мой 'malloc' всегда ** включает 'sizeof' для ясности и соображений безопасности (что, если размер структуры структуры данных?). Кроме того, спасибо за это объяснение о модифицированном UTF-8 Java. Я не мог найти ничего в документах JNI о том, включен ли 0-терминатор, поэтому я добавляю его вручную в свой код. –