C++初心者のため大変困っております。
正直に申し上げますと、だれか助けて下さい。
どなたかご教授宜しくお願いいたします。
まずは簡単な仕様から
JavaでC++を呼び出し、C++でハードウェアを動かします
ハードウェアから文字列を受け取り、Javaに返すというプログラムを開発しております。
以下に現在の状況を示します
・C++のプロジェクト→プロパティ→マルチバイト文字を使用する にチェックを入れました
・ソースです↓ 以下をJavaから呼び出し、戻り値を取得しています
printfがたくさんありますが、文字列をチェックするためのものです。ご了承ください。
JNIEXPORT jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj) {
BSTR s1 = ::SysAllocString(L"s1");
BSTR s2 = ::SysAllocString(L"s2");
BSTR s3 = ::SysAllocString(L"s3");
//ハードウェアにコマンドを送信する関数です
//レスポンスが、s3のアドレスに格納されます。
crwSendCommandRR(
4, //ポート番号
1, //ポーリングフラグ
10000, //タイマー
0, //タイマー
1, //DSR信号線チェックフラグ
"DT", //コマンドコード
":1", //ハードウェアに送信するパラメータ
2, //パラメータの長さ
&s1, //レスポンスを格納するアドレス 1
&s2, //レスポンスを格納するアドレス 2
&s3 //レスポンスを格納するアドレス 3
);
printf("s3:\n", s3);
printf("s3:%d\n", s3);
printf("s3:%x\n", s3);
printf("s3:%s\n", s3);
//BSTR を char に変換----------------------------------------------
char buf[64]="";
WideCharToMultiByte(
CP_ACP, // コードページ ANSI コードページ
WC_NO_BEST_FIT_CHARS,// 処理速度とマッピング方法を決定するフラグ
(OLECHAR*)s3, // ワイド文字列のアドレス
-1, // ワイド文字列の文字数
buf, // 新しい文字列を受け取るバッファのアドレス
sizeof(buf) - 1, // 新しい文字列を受け取るバッファのサイズ
NULL, // マップできない文字の既定値のアドレス
NULL // 既定の文字を使ったときにセットするフラグのアドレス
);
int len = strlen(buf);
for(int i = 0; i < len; i++) {
printf("\nbuf:", buf[i]);
printf("\nbuf:%d", buf[i]);
printf("\nbuf:%x", buf[i]);
}
char* src = buf;
printf("\nsrc:",src);
printf("\nsrc:%d",src);
printf("\nsrc:%x",src);
printf("\nsrc:%s",src);
jstring jstr = env->NewStringUTF(src);
printf("\njstr:", jstr);
printf("\njstr:%d", jstr);
printf("\njstr:%x", jstr);
printf("\njstr:%s", jstr);
::SysFreeString(s1);
::SysFreeString(s2);
::SysFreeString(s3);
return jstr;
}
・実行結果
Java側 ????? //?になります。本来なら 1:19900309
C++側
s3:
s3:3150196
s3:301174
s3:1:19900309
c:
c:3150196
c:301174
c:1:19900309
buf:
buf:63
buf:3f
buf:
buf:63
buf:3f
buf:
buf:63
buf:3f
buf:
buf:63
buf:3f
src:
src:71756992
src:446ecc0
src:????
jstr:
jstr:65927816
jstr:3edfa88
jstr:Pァ$@ヌ#@ヌ#@ヌ#(CO
どうもWideCharToMultiByteの使い方が悪いのかと思うんですが
C++初心者のため、どこがどうおかしいのか答えが出せずにおります
他に何かございましたら補足致しますので宜しくお願い致します。
No.1ベストアンサー
- 回答日時:
実行結果の
>s3:1:19900309
からするとs3はWideCharToMultiByte()を使うまでもなくマルチバイトキャラクターだと思いますが。
s3がワイドキャラクターならprintf()ではまともに出力できませんから。
そこから考えるとcrwSendCommandRR()の使い方も間違ってそうな気がします。
>C++初心者のため大変困っております。
内容からするとC++はあんまり関係ないと思う(C++の機能ぽいのほとんど使われてないし)
ひとまず
・ハードウェアから文字列受信
・JNIを使ってCからJavaに文字列を渡す
のをそれぞれに出来るようにしてから組み合わせた方がいいと思いますよ。
この回答への補足
ああ・・・
わたしは何とバカなことを・・・
以下のような簡単な処理で解決いたしました・・・
ご回答ありがとうございました。
やはりWideChartoなんたらは使う必要がなかったです。
ありがとうございました。
JNIEXPORT jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj) {
BSTR s1 = ::SysAllocString(L"s1");
BSTR s2 = ::SysAllocString(L"s2");
BSTR s3 = ::SysAllocString(L"s3");
ret = crwSendCommandRR(4,1,10000,0,1,"DT",":1",2,&s1,&s2,&s3);
printf("s3:\n", s3);
printf("s3:%d\n", s3);
printf("s3:%x\n", s3);
printf("s3:%s\n", s3);
//BSTR を char に変換----------------------------------------------
char* src = (char*)s3; ←これだけ!!!!!!!
printf("\nsrc:",src);
printf("\nsrc:%d",src);
printf("\nsrc:%x",src);
printf("\nsrc:%s",src);
jstring jstr = env->NewStringUTF(src);
printf("\njstr:", jstr);
printf("\njstr:%d", jstr);
printf("\njstr:%x", jstr);
printf("\njstr:%s", jstr);
::SysFreeString(s1);
::SysFreeString(s2);
::SysFreeString(s3);
return jstr;
}
java側 1:19900309
C++側
s3:
s3:1898084
s3:1cf664
s3:1:19900309
c:
c:1898084
c:1cf664
c:1:19900309
check
src:
src:1898084
src:1cf664
src:1:19900309
jstr:
jstr:66212024
jstr:3f250b8
jstr:弄$@ヌ#@ヌ#@ヌ#(CO
ご回答ありがとうございます
たしかに仕様書には
BSTR* 32ビットの文字ポインタ
としか書いてありませんでした。
どこかで勘違いをしていたと思います。
ありがとうございます。
・ハードウェアからの文字列受信
・JNIを使ってCからJavaに文字列を渡す
どちらも簡易的に行いましたが
BSTRが絡むと急にできなくなります。
BSTRについてもう少し調べてみようと思います
ありがとうございます。
No.2
- 回答日時:
>以下のような簡単な処理で解決いたしました・・・
解決したと思われてるようですが
>char* src = (char*)s3; ←これだけ!!!!!!!
上記で済んでWideCharToMultiByte()を使う必要がないということは
crwSendCommandRR()は第11引数にBSTR*を要求してるにもかかわらずBSTRでないものを格納している(正しいBSTRならワイドキャラクタ文字列なのでWideCharToMultiByte()を使う必要がある)ということなので
crwSendCommandRR()の処理がおかしいということになりますが・・・
crwSendCommandRR()を作成された方に仕様を確認した方がよいと思いますよ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
勝率をプログラムに
-
コンパイルエラーについて
-
台形の面積を求めるプログラム
-
cshの文字列操作(0埋め)
-
コマンドラインに出力した文字...
-
迷路作成のプログラミング
-
switch分のケースを範囲数?に...
-
printf で二進表示を行いたい。
-
三角形の判別
-
#include <stdio.h> #include <...
-
スレッドとメッセージキューに...
-
教えてください!!
-
C言語のプログラムにエラーが出...
-
インクリメント、デクリメント。
-
printfでSegmentation fault
-
10個出力で改行したいのですが...
-
正の実数Aを求めよまた、関数...
-
4の倍数を論理演算で表す。。
-
3つの整数が等しいかどうか調...
-
C++でfprintfやprintf,fopenな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
テキストカーソル位置の取得
-
4の倍数を論理演算で表す。。
-
cshの文字列操作(0埋め)
-
【C言語教えてください】sin波...
-
10個出力で改行したいのですが...
-
wsprintfの書式制御文字列につ...
-
error C2143: 構文エラー : ';'...
-
printfの出力内の文字をdefine...
-
%P と %X の違い
-
C言語
-
strcmp
-
(C言語)めちゃくちゃな値にな...
-
コマンドラインに出力した文字...
-
スレッドとメッセージキューに...
-
printf( " %2d", p * q );
-
Visual Sutdio 2017 でのC言語...
-
defineで定数が置き換えられな...
おすすめ情報