none
C#のコードをVC++2005に変換したいのですが、うまくいきません。 RRS feed

  • 質問

  • はじめまして、

    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;
     }

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

    2014年9月11日 0:44

回答

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

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

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

    • 回答としてマーク 星 睦美 2014年9月17日 5:48
    2014年9月11日 2:48

すべての返信

  • sizeof(ack_char)はsizeof(char *)なので、32bitの場合4Byteになりますよね。
    そこがまちがってませんか。1Byte送信すれば十分ですよね。
    2014年9月11日 0:53
  • どうも、お世話になります。

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

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

    2014年9月11日 2:28
  • そもそも静的な1Byte=0x06を送信するなら

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

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

    • 回答としてマーク 星 睦美 2014年9月17日 5:48
    2014年9月11日 2:48
  • >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 とは違う場所を指していませんか?

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

    C言語ポインタ完全制覇
    http://www.amazon.co.jp/gp/aw/d/4774111422?pc_redir=1409945068&robot_redir=1
    • 編集済み sygh 2014年9月11日 3:49
    2014年9月11日 3:15
  • お世話になります。

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

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

    2014年9月11日 4:33