ページ 11

System::IO::Ports::SerialPortでDataRecievedから呼び出す関数でエラーが発生します

Posted: 2013年1月08日(火) 04:01
by くぼたきく
VC++ 2010 Express + Win7(64bit)でシリアル通信アプリを作成しています。

System::IO::Ports::SerialPortを使い送信は、問題なくできました。
受信はプロパティ画面でDataReceivedに作成した関数を指定し受信もできたのですが、同関数内でテキストボックスに受信内容を表示する自作関数をcallしたところ下記メッセージが表示されました。

'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。
追加情報: 有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'txtLog' がアクセスされました。

ネットで検索したところ、delegate、invokeなどを使う必要があるのがわかり下記のように修正しましたが、コンパイルエラーが取れず困っています。
1)引数で渡そうとしているchar *をobject型に代入できない。
2)delegate前と後の関数(という表現がいいのか?)で型が一致しない。

当方、C言語およびVC++6.0などの経験は有りますが、VC++ 2010 Expressは初めてで勝手がわからず、文字を扱うにも四苦八苦しているような状態です。
どなたか解決策お分かりの方いらっしゃいましたら、アドバイスいただけると幸いです。


下記に、コンパイルエラーの内容と、問題のソースを記載します。

1>------ ビルド開始: プロジェクト: AAAAA, 構成: Debug Win32 ------
1> AAAAA.cpp
1>SSSS.h(63): warning C4101: 'ex' : ローカル変数は 1 度も使われていません。
1>FFFF.h(984): error C2440: '=' : 'char *' から 'System::Object ^' に変換できません。
1> 使用可能なユーザー定義された変換演算子がない、または
1> アンマネージ型をマネージ型に変換できません。
1>FFFF.h(986): error C3352: 'void AAAAA::Form1::PrintLog(char *,int)' : 指定された関数は delegate の型 'void (char *,int)' と一致しません。
1> SSSS.cpp
1>SSSSS.h(63): warning C4101: 'ex' : ローカル変数は 1 度も使われていません。
1>FFFFF.h(984): error C2440: '=' : 'char *' から 'System::Object ^' に変換できません。
1> 使用可能なユーザー定義された変換演算子がない、または
1> アンマネージ型をマネージ型に変換できません。
1>FFFF.h(986): error C3352: 'void AAAAA::Form1::PrintLog(char *,int)' : 指定された関数は delegate の型 'void (char *,int)' と一致しません。
1> コードを生成中...
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

コード:

	private: delegate System::Void PrintLogCallback(char *pData, int iNums);

	private: System::Void PrintLog(char *pData, int iNums) {
				 if(txtLog->InvokeRequired){
					array<Object^>^args = gcnew array<Object^>(2);
					args[0] = pData;
					args[1] = iNums;
					Invoke(gcnew PrintLogCallback(&AIOS485::Form1::PrintLog), args);
					return;
				}

				String^ strNum = "0123456789ABCDEF";

				if(iNums<1)
					return;

				// ログ出力
				for(int i=0; i<iNums; i++)
				{
					char c1, c2;
					c1 = *(pData+i) >> 4;
					c2 = *(pData+i) & 0x0F;
					txtLog->Text = txtLog->Text + strNum->Substring(c1, 1) + strNum->Substring(c2, 1) + " ";
				}
				txtLog->Text = txtLog->Text + "\r\n";
			 }


[code]

Re: System::IO::Ports::SerialPortでDataRecievedから呼び出す関数でエラーが発

Posted: 2013年1月08日(火) 08:27
by h2so5
const char* から System::Stringへの変換は

コード:

String^ strNum = gcnew String("0123456789ABCDEF");
で可能です。

VC++6.0 や VC++ 2010 Express は開発環境の名前であってC言語のような言語名ではありません。
そして、くぼたきくさんの書いているコードは C++/CLI という言語です。

C++/CLI は.netFrameworkとネイティブコードの橋渡しをするための言語で、
その必要がないアプリケーションを組むためにわざわざこの言語を利用するメリットはありません。
C++/CLIではなく、C#かC++を使うことを強くお勧めします。