質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

jstringをchar*にしたい

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 2,658

yukkuri

score 562

 前提・実現したいこと

jstringをchar*に変換して、文字列を描画したいです。

 発生している問題・エラーメッセージ

native\windows\Console.c: In function 'Java_org_yukkuri_jyl_base_JylConsole_nput':
native\windows\Console.c:8:24: error: request for member 'GetStringUTFChars' in something
not a structure or union
native\windows\Console.c:10:14: warning: incompatible implicit declaration of built-in fun
ction 'strdup'
native\windows\Console.c:14:5: error: request for member 'ReleaseStringUTFChars' in someth
ing not a structure or union

 該当のソースコード

#include <stdio.h>

#include "jni.h"
#include "org_yukkuri_jyl_base_JylConsole.h"

JNIEXPORT void JNICALL Java_org_yukkuri_jyl_base_JylConsole_nput( JNIEnv *env, jclass cls, jstring message )
{
    const char* cmsg = env->GetStringUTFChars( message, 0 );

    char* msg = strdup( cmsg );

    printf( msg );

    env->ReleaseStringUTFChars( message, cmsg );
}

 試したこと

ネットを調べてもよくわかりませんでした。

 補足情報(FW/ツールのバージョンなど)

MinGWを使用しています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

ぱっとすぐにわかる問題を指摘します。

strdup は以下のヘッダファイルのインクルードが必要です。

 #include <string.h>


また、提示されているコードで言えば、strdup 自体不要です。以下の wikipedia のように直接 printf して問題ありません。※日本語が入っていない場合
https://ja.wikipedia.org/wiki/Java_Native_Interface

上記ページに記載のある通り以下の2つの呼び出しは

env->GetStringUTFChars( message, 0 );
env->ReleaseStringUTFChars( message, cmsg );


C では以下のように記述する必要があります。

(*env)->GetStringUTFChars( env, message, 0 );
(*env)->ReleaseStringUTFChars( env, message, cmsg );


上記以外の問題がある場合、質問に追記してください。


2018/10/23 追記
日本語を表示する必要がある場合、いろいろやり方はありますが、代表的な2件を紹介しておきます。

 1.コマンドプロンプトのコードページを UTF-8 に変更

コマンドプロンプトのコードページを UTF-8 に変更すると GetStringUTFChars の戻り値である文字列を直接出力することができます。

chcp 65001

この場合、元のソースを修正する必要はありません。

 2.UTF-8 を Shift-JIS に変換して出力

コマンドプロンプトはもともと Shift-JIS なので UTF-8 文字列を Shift-JIS に変換して出力すれば問題ありません。以下のようなコードになります。

#include <windows.h>
#include <stdio.h>

#include "jni.h"
#include "org_yukkuri_jyl_base_JylConsole.h"

JNIEXPORT void JNICALL Java_org_yukkuri_jyl_base_JylConsole_nput( JNIEnv *env, jclass cls, jstring message )
{
    const char* cmsg = (*env)->GetStringUTFChars( env, message, 0 );

    // UTF-8 => Unicode
    int widecharlength = MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, NULL, 0 );
    wchar_t* wmsg = malloc( sizeof(wchar_t) * (widecharlength + 1) );
    MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, wmsg, widecharlength + 1 );

    // Unicode => Shift-JIS
    int sjislength = WideCharToMultiByte( CP_ACP, 0, wmsg, -1, NULL, 0, NULL, NULL );
    char* msg = malloc( sjislength + 1 );
    WideCharToMultiByte( CP_ACP, 0, wmsg, -1, msg, sjislength + 1, NULL, NULL );

    printf( "%s", msg );

    // 確保した文字列のメモリを解放する。
    free( wmsg );
    free( msg );

    (*env)->ReleaseStringUTFChars( env, message, cmsg );
}

通常は JNI でもプラットフォーム互換を考慮して iconv 等を使用しますが、今回は MinGW 限定ということで Windows API を使用しています。malloc/free でコンパイルエラーになる場合、適宜必要なヘッダを追記してください。


2018/10/24 追記
TEXT マクロ(回答では _TEXT ですが)を使用する場合、明確にコードを分ける必要がでてきます。UTF-8 の文字列は char の配列であるため、これを Shift-JIS の char 配列 または wchar_t の配列に変換することになります。

#include <windows.h>
#include <tchar.h>

#include "jni.h"
#include "org_yukkuri_jyl_base_JylConsole.h"

JNIEXPORT void JNICALL Java_org_yukkuri_jyl_base_JylConsole_nput( JNIEnv *env, jclass cls, jstring message )
{
    /* UTF-8文字列は TCHAR* ではなく char* に格納する。*/
    const char* cmsg = (*env)->GetStringUTFChars( env, message, 0 );

#ifdef _UNICODE
    /*
     * UTF-8 => Unicode
     * _UNICODE の場合、wchar_t にまで変換すれば問題ない。
     */
    int widecharlength = MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, NULL, 0 );
    wchar_t* msg = malloc( sizeof(wchar_t) * (widecharlength + 1) );
    MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, msg, widecharlength + 1 );
#else
    /*
     * UTF-8 => Unicode
     * _UNICODE の定義がない場合、char に変換する必要があるため、UTF-8 => Unicode => Shift-JIS の順に変換する。
     */
    int widecharlength = MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, NULL, 0 );
    wchar_t* wmsg = malloc( sizeof(wchar_t) * (widecharlength + 1) );
    MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, wmsg, widecharlength + 1 );

    /* Unicode => Shift-JIS */
    int sjislength = WideCharToMultiByte( CP_ACP, 0, wmsg, -1, NULL, 0, NULL, NULL );
    char* msg = malloc( sjislength + 1 );
    WideCharToMultiByte( CP_ACP, 0, wmsg, -1, msg, sjislength + 1, NULL, NULL );

    free( wmsg );
#endif

    _tprintf( _TEXT("%s"), msg );

    /* 確保した文字列のメモリを解放する。*/
    free( msg );

    (*env)->ReleaseStringUTFChars( env, message, cmsg );
}

上の例では _UNICODE マクロしか対応していませんが、ヘッダファイルの中にはアンダースコア無しの UNICODE マクロで記載されているものもあります。コンパイル時には両方指定することをお勧めします。Unicode でコンパイルしない場合、当然ですが両方指定しないことになります。

この場合、当然ですが最初にあげているコマンドプロンプトの文字コードを UTF-8 にする対応では対応できなくなります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/23 21:10

    ありがとうございます。tchar.hのTEXTマクロを使用して日本語を表示するとしたら、どうすればいいでしょうか。ご教授お願いします。

    キャンセル

  • 2018/10/24 02:52

    回答に追記しました。ご確認ください。

    キャンセル

  • 2018/10/24 18:40

    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る