【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?

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++初心者のため、どこがどうおかしいのか答えが出せずにおります
他に何かございましたら補足致しますので宜しくお願い致します。

A 回答 (2件)

実行結果の



>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

補足日時:2012/06/07 10:41
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます
たしかに仕様書には
BSTR* 32ビットの文字ポインタ
としか書いてありませんでした。
どこかで勘違いをしていたと思います。
ありがとうございます。

・ハードウェアからの文字列受信
・JNIを使ってCからJavaに文字列を渡す
どちらも簡易的に行いましたが
BSTRが絡むと急にできなくなります。

BSTRについてもう少し調べてみようと思います

ありがとうございます。

お礼日時:2012/06/07 09:05

>以下のような簡単な処理で解決いたしました・・・



解決したと思われてるようですが

>char* src = (char*)s3;   ←これだけ!!!!!!!

上記で済んでWideCharToMultiByte()を使う必要がないということは
crwSendCommandRR()は第11引数にBSTR*を要求してるにもかかわらずBSTRでないものを格納している(正しいBSTRならワイドキャラクタ文字列なのでWideCharToMultiByte()を使う必要がある)ということなので
crwSendCommandRR()の処理がおかしいということになりますが・・・
crwSendCommandRR()を作成された方に仕様を確認した方がよいと思いますよ。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!