Question

ferret001 on Thu, 11 Sep 2014 00:44:17


はじめまして、

VS2005 VC++で大昔に作ったアプリが社内でまだ動いているものがあり、修正を頼まれました。

その個所は、シリアルポートを使用している箇所で、相手の機械が新しくなり通信フォーマットが変更になったとのことです。フォーマットの変更自体問題ないのですが、送信するファイル容量が増えるため2つに分けて送るとのことです。実際には、受信側は、1つ目を受けたらACK(06h)を返し次を受け取るとのこと。これを試しに、現在のVS2010 C#で下記のように書くとうまく受け取れますが、C#のコードをVC++に変換がうまくいきません。

C#(下記だとうまく次のレコードが受け取れます。)

byte[] ack_data = new byte[1];
ack_data[0] = 06;

serialPort1.Write(ack_data, 0, ack_data.Length);

VC++(下記のように書いてみたけど、ハングアップする、または、送信エラーと言ってくる)

char *ack_char;  // = '06'; 
memset(ack_char, 0x06, sizeof(ack_char));
++ack_char=0;
serial.Send(ack_char, sizeof(ack_char));

// 文字列送信
int CSerial::Send(const char *data, int size)
{
 DWORD bytes = 0;

 BOOL b = ::WriteFile(m_hIDComDev, data, size, &bytes, NULL);

 if(!b)  {
  AfxMessageBox("送信エラー、書き込みに失敗しました。");
  return 0;
 }

教えてください、よろしくお願いします。


Sponsored



Replies

仲澤@失業者 on Thu, 11 Sep 2014 00:53:23


sizeof(ack_char)はsizeof(char *)なので、32bitの場合4Byteになりますよね。
そこがまちがってませんか。1Byte送信すれば十分ですよね。

ferret001 on Thu, 11 Sep 2014 02:28:30


どうも、お世話になります。

char *ack_char; 
memset(ack_char, 0x06, 1/*sizeof(ack_char)*/);
++ack_char=0;
serial.Send(ack_char, 1/*sizeof(ack_char)*/);

のように変更して試してみる。ということでよろしいのでしょうか?さっそく試してみます。

仲澤@失業者 on Thu, 11 Sep 2014 02:48:22


そもそも静的な1Byte=0x06を送信するなら

::WriteFile( m_hIDComDev, "\x06", 1, &bytes, NULL);

の様な、疑問の余地のないコードにすべきかもしれません。

しまとしき on Thu, 11 Sep 2014 03:04:40


>char *ack_char;

>memset(ack_char, 0x06, 1);

>++ack_char = 0;

>serial.Senc(ack_char, 1);

char *ack_char;   ////このままだと、どこを指しているか分りますか?

memset(ack_char, 0x06, 1);    ////どこを指しているか不明なポインターを使ってメモリー操作をしています。

++ack_char =0;   ////これは何を操作しているのですか?

////ポインターを進めることと、ポインターの示すメモリーに代入することとは別の表現になるはずでしょう

////*(ack_char + 1) = 0; ならまだ意図が分ります。

serial.Send(ack_char, 1);    ////ack_char は動かした後のポインターなので、 0x06 とは違う場所を指していませんか?

sygh on Thu, 11 Sep 2014 03:15:50


しまとしきさんと同意見ですが、質問者さんはポインタや固定長配列・可変長配列をまったく理解していないように思います。
提示コードはなんらかの途中処理を省いているだけなのかも知れませんが、仮にそうだとしても道理の通らない箇所があります。
ポインタが分からないのにC#コードをC++に移植しようと試みるのはどう考えても無謀でしょう。
取り返しのつかない事態になる前に、まずポインタを基礎から徹底的に勉強することを強く推奨します。

C言語ポインタ完全制覇
http://www.amazon.co.jp/gp/aw/d/4774111422?pc_redir=1409945068&robot_redir=1

ferret001 on Thu, 11 Sep 2014 04:33:08


お世話になります。

そうですね。そのコードを送る部分を関数にして呼び出した方が、簡単ですね。

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