voidポインタをハンドルへ

このQ&Aのポイント
  • Form1で作成したlogBoxというTextBoxをハンドルにする方法を教えてください。
  • 質問者はForm1で作成したlogBoxというTextBoxを他のソースファイルでも使用したいと考えています。しかし、現在はエラーが出ており、解決方法を知りたいとしています。
  • エラーメッセージは、voidポインタをSystem::Windows::Forms::TextBoxに変換できないというものです。どのようにすればこのエラーを解決することができるでしょうか?
回答を見る
  • ベストアンサー

voidポインタをハンドルへ

voidポインタをハンドルへ 今、Form1でlogBoxというTextBoxを作成し、Form1.h以外ののソースからでも、エラーが出た場合そこにLogが吐き出されるようにしようとしています。 //clrres.h void *LOGBOX; void OutText(TextBox^ b,String^ s); extern inline void OUTPUTLOG(String ^s); //clrres.cpp #include "stdafx.h" #include"clrres.h" void OutText(TextBox^ b,String^ s){   b->AppendText(s+L"\r\n");   b->SelectionStart = b->Text->Length;   b->ScrollToCaret(); } inline void OUTPUTLOG(String ^s){   OutText((TextBox^)LOGBOX,s); } //Form1.hのForm1コンストラクタ内 System::IntPtr ptr=logBox->Handle; LOGBOX=ptr.ToPointer(); とすれば、簡単に、Logを書き出せるようになるかと考えたのですが、 error C2440: '型キャスト' : 'void *' から'System::Windows::Forms::TextBox ^' に変換できません。 と出てきます。 どの様にすれば、出来るようになるでしょうか? 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

すいません、変換部分は大嘘ぶっこきました。 Control.FromHandleにIntPtrを渡します。 OutText((TextBox^)Control.FromHandle(IntPtr(LOGBOX)),s); ただし、いずれにせよ例外は発生するはずですので、#1でも言ったようにデリゲートを使うか前回も言ったように例外発生しないように設定を変えるかしてください。 ログを書き込む部分をForm1のパブリックメンバ関数にしてそこからデリゲートを使うようにすれば記述もそう面倒ではないはずです。

glarelance
質問者

お礼

たびたび、どうも有り難うございます。 実は、CUIのC++で使っていたヘッダファイルを.NetでGUIを作った場合でも、OUTPUTLOG周りをちょっと書き換えればどっちでも直ぐに使えるヘッダファイルとしてclrres.hを作りたいなと考えているんです。 そこで、Form1に書き込む部分をForm1の中にstatic関数として作成しました。 ただ、これを呼び出そうとすると、clrres.hにForm1.hをインクルードしなければいけません。しかし、Form1.hで使用する関数をclrres.hとclrres.cppで作成していたので、当然Form1.hにもclrres.hがincludeされています。 そのため、どちらかのファイルからもう片方が読み込まれると、読み込まれたファイルもそのファイル自身を読み込んだファイルを読み込もうとします。 しかし、#pragma onceが入っているので、もう片方のファイルに定義されている定義が読み込めずcompileエラーが出ます。 これは、clrres.hに hogehoge{   class Form1;   void Form1::kakidasi(String^ s); } みたいにクラスを前に定義しておくのと同じ感じで書いておけばいけるかなと考えたのですが、このような関数の書き方はだめ、みたいな感じでコンパイラに怒られます。 どの様にすればうまくいくのでしょうか?

その他の回答 (2)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

そこまで行くともはや別の質問って感じですが…… VC++のデザイナ頼りだとついついヘッダに全部書いてしまいますが、C++/CLIも基本はC++ですからヘッダとコードは分離可能です。 シンボル参照の循環が問題ならそれで解消できるかと思いますが、どうですか?

glarelance
質問者

お礼

確かにこの方法でうまく書き込めるようになりました 特にコンソールアプリしか作らなかったころは、voidポインタなんて何に使うのかよく分からなかったですが、色んなライブラリを組み合わせてデータの受け渡しするときには物凄く便利ですね どうも有り難うございました。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

http://okwave.jp/qa5015628.html の続きということなのでしょうが、あの例外は「コントロールのオーナー以外がコントロールを操作しようとしている」って事なので、たとえ変換が出来ても結局は同じ例外が発生するだけのはずです。 素直にデリゲートを使ってください。 なお、void *→IntPtrへはIntPtrのコンストラクタを経由して変換可能なので、 OutText((TextBox^)IntPtr(LOGBOX),s); とすれば文法上の問題はなくなるのではないかと。

関連するQ&A

  • ポインタについて

    #include<stdio.h> int main(void) { char str[10]; char *ptr = str; printf("文字列を入力してください。\n"); scanf("%s",ptr); printf("文字列は%sです。",str); return 0; } 上記のプログラムのscanf("%s",ptr);の ptrに&をつけるとなぜ先頭の4文字は入力しても 表示されなくなってしまうのでしょうか? よろしくお願いします。

  • void型ポインタについて

    -------------------------------- #include<stdio.h> void uni_disp(void *p,int typ); int main() { int idt=123456; double ddt=56.789; char ss[]="abcdef"; uni_disp(&idt,'I'); uni_disp(&ddt,'D'); uni_disp(ss,'S'); uni_disp("STRING",'S'); return 0; } void uni_disp(void *p,int typ) { if(typ=='I'){ printf("%d\n",*(int *)p); } else if(typ=='D'){ printf("%f\n",*(double *)p); } else if(typ=='S'){ printf("%s\n",(char *)p); } } ----------------------------------- 以上のプログラム等で、void型ポインタをint型ポインタ、double型ポインタとみなす場合の、「*(int *)p」や「*(double *)p」の表記がどういう仕組みになっているか分かりません。 「*(int)p」などはエラーが出るのですが、やはり表記の意味を理解していないため何故か分かりません。 「*(int *)p」などの表記を分解して教えていただけると嬉しいです。

  • 参照渡し と ポインタ渡し

    参照渡し と ポインタ渡し はどういう時に使い分けるんですか? VOID型の自作関数内でメインのブール値を書き替えたいんだけど #include <iostream.h> void ref( int &b ) { b = false; } void ptr( int *b ){ ( *b ) = true; } main(){  bool b = true;  ref( b );  cout << b;  ptr( &b );  cout << b; } だとコンパイルエラーでした。 うまくいくソースを教えてください。

  • voidポインタ

    教えて頂けますか? 環境は mac osx です。 とあるページのサンプルコード #include <stdio.h> void outString(void *); int main() { int i = 65 ; double d = 10.101; outString(&i); outString(&d); outString("Kitty on your lap"); return 0; } void outString(void *text) { char *str = (char *)text; printf("%s\n" , str); } を実行した次のように表示されました A \301ʡE\2663$@\234\367\377\277A Kitty on your lap 二行目はどういう事になっているのでしょう? ちなみに d = 65.0; で実行しましたが A とは表示されませんでした。 自分の環境のせいでしょうか? よろしくお願いします

  • ポインタの文字の代入について

    素朴な疑問ですが、なぜ宣言文の時には*ptrに文字列を代入してもエラーが出ないのに、宣言文以外のところで下記の記述をするとエラーが出るのですか? #include<stdio.h> void main(void) { char *ptr = "DEF"; *ptr = "ABC";//コンパイルエラー      ptr = "ABC";//正常 }

  • C言語のプログラミングでつまずいてます

    ポインタをりようする。string.hとctype.hに含まれる関数は使用しないこと。 以下の実行例のように、文字列を受け取り、アルファベットの大文字を小文字にして表示する関数を作成したいのですが 実行例: Original string is <AbCdE1f2> Modified string is <abcde1f2> #include <stdio.h> #define NUMOFCHAR 10 void print_char(char *ptr); int main(void) { char string[NUMOFCHAR+1]; printf("Input a sentence (# of letters <= %d): ", NUMOFCHAR); fflush(stdout); scanf("%s", string); string[NUMOFCHAR] = '\0'; printf("Original string is <%s>\n", string); printf("Modified string is <"); print_char(string); printf(">\n"); return 0; } void print_char(char *ptr) { int i=0; for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); } よ書いたのですがビルドえらーがおこります。 どこがだめなのかわかりません。。。 C言語に詳しい人でわかるかた、どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 お願いします

  • [C]char型のダブルポインタ

    粗雑で申し訳ありませんが、 以下のソースをコンパイルできましたが、 うまく実行できません。 自分なりに間違いがないと思うのですが、 間違い等をご指摘頂ければ助かります。 #include <stdio.h> void func(char **ptr) ptr[][10] か (*ptr)[] なら通る *ptr[] は通らない { printf("----- func -----"); printf("%s\n", *ptr); printf("%c\n", **ptr); putchar('\n'); } int main(void) { char str[5][10] = {"AAAAA", *str[] にすると func で **ptr で通る "BBBBB", "CCCCC", "DDDDD", "EEEEE", }; printf("----- main -----"); printf("%s\n", *str); printf("%c\n", **str); putchar('\n'); func(str); return (0); } 実行結果 ----- main ----- AAAAA A ----- func ----- Bus error (core dump) 関数への受け渡しで、型が違うというお叱りを受けますが、 コンパイルはできました。 コンパイラはCCです。 ではよろしくお願いします。

  • ポインタと配列について教えてください。

    #include <stdio.h> int main(void) { int i; int vc[5] = {10,20,30,40,50}; int *ptr = &vc[0]; for(i = 0; i < 5; i++) printf("vc[%d] = %d ptr[%d] = %d *(ptr + &d) = %d\n", i, vc[i], i, ptr[i], i, *(ptr + 1)); return(0); } というプログラムで実行結果は vc[0]=10 ptr[0]=10 *(ptr +0 )=10 vc[1]=20 ptr[1]=20 *(ptr +1 )=20 vc[2]=30 ptr[2]=30 *(ptr +2 )=30 vc[3]=40 ptr[3]=40 *(ptr +3 )=40 vc[4]=50 ptr[4]=50 *(ptr +4 )=50 となるのですが、なぜこうなるのか分かりません。 int *ptr = &vc[0]; の行では、vc[0]のアドレスを *ptrに代入するという意味ではないのでしょうか?

  • 別スレッドからメインスレッドのテキストボックスに文字を表示させたい

    Visual C++ 2005 Express Editionを使用している初心者です。 タイトルの方法がどうしてもわからないので教えてください。 うまく説明できないので聞きたいところのコードを載せます。 //SAMPLE.cpp #include "stdafx.h" #include "Form1.h" using namespace SAMPLE; int main(array<System::String ^> ^args) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew Form1()); } //Form1.h #include <process.h> #include <vcclr.h> namespace SAMPLE { unsigned __stdcall counter(void *arg); int thread_id1; unsigned dummy; using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; public ref class Form1 : public System::Windows::Forms::Form { public:Form1(void) { InitializeComponent(); //別スレッド起動 thread_id1=_beginthreadex(NULL,0,counter,(void *)1,0,&dummy); } private: System::Windows::Forms::TextBox^ textBox1; private: System::ComponentModel::Container ^components; void InitializeComponent(void) { this->textBox1 = (gcnew System::Windows::Forms::TextBox()); //省略(コンポーネント初期化) } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { } }; unsigned __stdcall counter(void *arg){ //別スレッド //ここで文字列を記述して上のtextBox1に表示したい return 0; } } 初歩的なことかもしれませんが、 よろしくお願いします。

  • C言語 ポインタ エラー

    文字列を入力後改行して入力した文字列を出力したいのですが、エラーがでます。 ハンドルされない例外が 0xFEFEFEFE (helloworld.exe) で発生しました: 0xC00001A5: 無効な例外ハンドラー ルーチンが検出されました。 (パラメーター: 0x00000003)。 調べてみましたが、理解できません 何卒よろしくお願いします。 #include <stdio.h> void put_string(const char *str) { while (*str) putchar(*str++); } int main(void) { char str[100]; printf("文字列を入力してください"); scanf_s("%s", str); put_string(str); putchar('\n'); return(0); }

専門家に質問してみよう