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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

JNI

JNI(Java Native Interface)は、Javaプラットフォームにおいて、Javaで記述されたプログラムと、他の言語で書かれたネイティブコードを連携するためのインタフェース仕様である

Q&A

解決済

1回答

3180閲覧

jstringをchar*にしたい

yukkuri

総合スコア624

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

JNI

JNI(Java Native Interface)は、Javaプラットフォームにおいて、Javaで記述されたプログラムと、他の言語で書かれたネイティブコードを連携するためのインタフェース仕様である

1グッド

1クリップ

投稿2018/10/21 16:40

前提・実現したいこと

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

該当のソースコード

C

1#include <stdio.h> 2 3#include "jni.h" 4#include "org_yukkuri_jyl_base_JylConsole.h" 5 6JNIEXPORT void JNICALL Java_org_yukkuri_jyl_base_JylConsole_nput( JNIEnv *env, jclass cls, jstring message ) 7{ 8 const char* cmsg = env->GetStringUTFChars( message, 0 ); 9 10 char* msg = strdup( cmsg ); 11 12 printf( msg ); 13 14 env->ReleaseStringUTFChars( message, cmsg ); 15} 16

試したこと

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

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

MinGWを使用しています。

atata0319👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

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

C

1 #include <string.h>

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

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

C++

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

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

C

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

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


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

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

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

cmd

1chcp 65001 2```この場合、元のソースを修正する必要はありません。 3### 2.UTF-8 を Shift-JIS に変換して出力 4コマンドプロンプトはもともと Shift-JIS なので UTF-8 文字列を Shift-JIS に変換して出力すれば問題ありません。以下のようなコードになります。 5```C 6#include <windows.h> 7#include <stdio.h> 8 9#include "jni.h" 10#include "org_yukkuri_jyl_base_JylConsole.h" 11 12JNIEXPORT void JNICALL Java_org_yukkuri_jyl_base_JylConsole_nput( JNIEnv *env, jclass cls, jstring message ) 13{ 14 const char* cmsg = (*env)->GetStringUTFChars( env, message, 0 ); 15 16 // UTF-8 => Unicode 17 int widecharlength = MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, NULL, 0 ); 18 wchar_t* wmsg = malloc( sizeof(wchar_t) * (widecharlength + 1) ); 19 MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, wmsg, widecharlength + 1 ); 20 21 // Unicode => Shift-JIS 22 int sjislength = WideCharToMultiByte( CP_ACP, 0, wmsg, -1, NULL, 0, NULL, NULL ); 23 char* msg = malloc( sjislength + 1 ); 24 WideCharToMultiByte( CP_ACP, 0, wmsg, -1, msg, sjislength + 1, NULL, NULL ); 25 26 printf( "%s", msg ); 27 28 // 確保した文字列のメモリを解放する。 29 free( wmsg ); 30 free( msg ); 31 32 (*env)->ReleaseStringUTFChars( env, message, cmsg ); 33} 34```通常は JNI でもプラットフォーム互換を考慮して iconv 等を使用しますが、今回は MinGW 限定ということで Windows API を使用しています。malloc/free でコンパイルエラーになる場合、適宜必要なヘッダを追記してください。 35 36--- 37**2018/10/24 追記** 38TEXT マクロ(回答では _TEXT ですが)を使用する場合、明確にコードを分ける必要がでてきます。UTF-8 の文字列は char の配列であるため、これを Shift-JIS の char 配列 または wchar_t の配列に変換することになります。 39```C 40#include <windows.h> 41#include <tchar.h> 42 43#include "jni.h" 44#include "org_yukkuri_jyl_base_JylConsole.h" 45 46JNIEXPORT void JNICALL Java_org_yukkuri_jyl_base_JylConsole_nput( JNIEnv *env, jclass cls, jstring message ) 47{ 48 /* UTF-8文字列は TCHAR* ではなく char* に格納する。*/ 49 const char* cmsg = (*env)->GetStringUTFChars( env, message, 0 ); 50 51#ifdef _UNICODE 52 /* 53 * UTF-8 => Unicode 54 * _UNICODE の場合、wchar_t にまで変換すれば問題ない。 55 */ 56 int widecharlength = MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, NULL, 0 ); 57 wchar_t* msg = malloc( sizeof(wchar_t) * (widecharlength + 1) ); 58 MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, msg, widecharlength + 1 ); 59#else 60 /* 61 * UTF-8 => Unicode 62 * _UNICODE の定義がない場合、char に変換する必要があるため、UTF-8 => Unicode => Shift-JIS の順に変換する。 63 */ 64 int widecharlength = MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, NULL, 0 ); 65 wchar_t* wmsg = malloc( sizeof(wchar_t) * (widecharlength + 1) ); 66 MultiByteToWideChar( CP_UTF8, 0, cmsg, -1, wmsg, widecharlength + 1 ); 67 68 /* Unicode => Shift-JIS */ 69 int sjislength = WideCharToMultiByte( CP_ACP, 0, wmsg, -1, NULL, 0, NULL, NULL ); 70 char* msg = malloc( sjislength + 1 ); 71 WideCharToMultiByte( CP_ACP, 0, wmsg, -1, msg, sjislength + 1, NULL, NULL ); 72 73 free( wmsg ); 74#endif 75 76 _tprintf( _TEXT("%s"), msg ); 77 78 /* 確保した文字列のメモリを解放する。*/ 79 free( msg ); 80 81 (*env)->ReleaseStringUTFChars( env, message, cmsg ); 82} 83```上の例では _UNICODE マクロしか対応していませんが、ヘッダファイルの中にはアンダースコア無しの UNICODE マクロで記載されているものもあります。コンパイル時には両方指定することをお勧めします。Unicode でコンパイルしない場合、当然ですが両方指定しないことになります。 84 85この場合、当然ですが最初にあげているコマンドプロンプトの文字コードを UTF-8 にする対応では対応できなくなります。

投稿2018/10/21 18:35

編集2018/10/23 17:51
atata0319

総合スコア881

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukkuri

2018/10/21 23:03

日本語を出力する場合どうしたらいいのでしょうか。
atata0319

2018/10/22 16:24

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

2018/10/23 12:10

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

2018/10/23 17:52

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

2018/10/24 09:40

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問