- 優希
- ベテラン
- 会議室デビュー日: 2003/08/12
- 投稿数: 92
|
投稿日時: 2004-02-02 21:16
お世話になります。
優希です。
DLL同士の通信について、質問があります。
開発環境は、Visual Studio .NET(VC++)、Windowsフォームを使って行います。
まず、
親画面上に、PictureBox1, PictureBox2を2つ作成し、
そのPictureBoxのそれぞれで非同期呼び出し(BeginInvoke()使用)で、
DLLをコールし、子画面を作成します。
※下記のソースはかなり端折ってありますので、
コンパイルが通るかわかりません (^^; )
その点は、ご勘弁ください。m(_ _)m
コード: |
|
///
/// 親画面の生成
///
public __gc class ParentForm: public Form
{
public:
// 子画面生成用デリゲート
__delegate void MakeChildHandler(String *strDllName,
PictureBox *picChild);
// コンストラクタ
ParentForm()
{
// Form生成
this->Location = Point(0, 0);
this->Size = Drawing::Size(1280, 1024);
// 子画面ウィンドウ1の表示用PictureBox
PictureBox *picBack_1 = new PictureBox();
picBack_1->Location = Point(10, 10);
picBack_1->Size = Drawing::Size(500, 500);
this->Controls->Add(picBack_1);
// 子画面1生成
Object *param[] = new Object*[2];
param[0] = S".\\Child1.dll"; // DLL名称
param[1] = picBack_1; // 子画面を追加するPictureBox
picBack_1->BeginInvoke(new MakeChildHandler(picBack_1, MakeChildForm), param);
// 子画面ウィンドウ2の表示用PictureBox
PictureBox *picBack_2 = new PictureBox();
picBack_2->Location = Point(510, 10);
picBack_2->Size = Drawing::Size(500, 500);
this->Controls->Add(picBack_2);
// 子画面2生成
param[0] = S".\\Child2.dll"; // DLL名称
param[1] = picBack_2; // 子画面を追加するPictureBox
picBack_2->BeginInvoke(new MakeChildHandler(picBack_2, MakeChildForm), param);
};
// 子画面表示
void MakeChildForm(String *strDllName, PictureBox *picChild)
{
// アセンブリの読み込み
Assembly *asmb = Assembly::LoadFrom(strDllName);
// インスタンスの生成
IWrapDll *wrapInst = dynamic_cast<IWrapDll*>(asmb->CreateInstance(S"ChildForm"));
if(wrapInst != 0){
wrapInst->DisplayWindow(picChild);
}
};
};
|
そして、
子画面上には、TextBoxを作成します。
コード: |
|
///
/// 子画面1の作成
///
public __gc class ChildForm
{
public:
// 変数
TextBox *textBox1;
// 子画面1の生成
void DisplayWindow(PictureBox *picBase)
{
// テキストボックス1の追加
textBox1 = new TextBox();
textBox1->Location = Point(20, 20);
textBox1->Size = Drawing::Size(50, 25);
picBase->Controls->Add(textBox1);
};
// テキストボックス1の内容を取得
String *GetData()
{
return textBox1->Text;
};
};
|
そこで、
子画面2から子画面1中のTextBox1のTextを取得しようと思い、
以下のようにコーディングしました。
コード: |
|
///
/// 子画面2の作成
///
public __gc class ChildForm
{
public:
// テキストボックス2
TextBox *textBox2;
// 子画面2の生成
void DisplayWindow(PictureBox *picBase)
{
// テキストボックス2の追加
textBox2 = new TextBox();
textBox2->Location = Point(20, 20);
textBox2->Size = Drawing::Size(50, 25);
picBase->Controls->Add(textBox2);
// タイマー処理で子画面1のテキストボックスの
// 内容を取得する
sTimer = new Timers::Timer(5000);
sTimer->Elapsed += new Timers::ElapsedEventHandler(picBase, sTimer_TimerEvent);
sTimer->Enabled = true;
};
// タイマー処理
void sTimer_TimerEvent(Object* sender, Timers::ElapsedEventArgs* e)
{
// アセンブリの読み込み
Assembly *asmb = Assembly::LoadFrom(S".\\Child1.dll");
// インスタンスの生成
IWrapDll *wrapInst = dynamic_cast<IWrapDll*>(asmb->CreateInstance(S"ChildForm"));
if(wrapInst != 0){
String *strTextContent = wrapInst->GetData(); // TextBox1の内容を取得
if(strTextContent != 0){
// テキストボックス1の内容を表示
textBox2->Text = strTextContent;
}
}
};
};
|
ところが、変数strTextContentはNULLになってしまい、
うまく取得することが出来ませんでした。
これは非同期呼び出しで行なっているからなのでしょうか?
変数strTextContentがNULLにならずに、
内容がきちんと取れる方法があれば、アドバイスをお願い致します。
以上、宜しくお願い致します。
|
- Jitta
- ぬし
- 会議室デビュー日: 2002/07/05
- 投稿数: 6267
- お住まい・勤務地: 兵庫県・海手
|
投稿日時: 2004-02-03 06:26
DLLをロードしてしても、それは実行中のモノと違いますから・・・
親画面に中継させるのが一番簡単ですが、DLL同士が直接通信しなければなりませんか?
|
- 優希
- ベテラン
- 会議室デビュー日: 2003/08/12
- 投稿数: 92
|
投稿日時: 2004-02-03 06:53
ご回答、ありがとう御座います。
そうですねぇ、
DLL同士で直接通信させたいと思っています。
これは、可能なのでしょうか?
DLL同士で直接通信させる方法や、
親画面に中継させるの方法がありましたら、
具体的な実装方法をお聞かせください。
宜しくお願い致します。
|
- Jitta
- ぬし
- 会議室デビュー日: 2002/07/05
- 投稿数: 6267
- お住まい・勤務地: 兵庫県・海手
|
投稿日時: 2004-02-03 08:30
中継させるなら、「発信」をイベントやデリゲートで通知します。「受信」はメソッド呼び出し。親画面は作成した子画面を“知っている”はずですから、そのインスタンスを使用します。
直接なら、「メッセージ」かな?インスタンスに直接送るorキューがたまったことをイベントのように知ることができるのかどうか、調べていないのでわかりませんが、キューを定期的に見に行くなどで対応できるでしょう。MSDNで、「フィルタ」を「.NET Framework」にし、「メッセージ」または「メッセージ キュー」でキーワード検索してみてください。「メッセージボックス」は違いますから、注意してください。
具体的…コード例ですか?私としては、コードまで示してしまうとそこで「知る」が停まってしまうと思うので、「これを使えばできるから後は調べてね」で止めたいのですが・・・
#興味はあるので、時間があれば作るかも、ということで。。。
|
- 優希
- ベテラン
- 会議室デビュー日: 2003/08/12
- 投稿数: 92
|
投稿日時: 2004-02-03 09:00
アドバイス、ありがとうございます。
早速、調べて作成して見たいと思います。
また何かありましたら、宜しくお願い致します。
|
- 優希
- ベテラン
- 会議室デビュー日: 2003/08/12
- 投稿数: 92
|
投稿日時: 2004-02-03 16:00
「メッセージキュー」で検索した結果、
"MSMQ"というAPIが見つかりました。
これって、ソフトをインストールしないと、
使えないものなのでしょうか?
試しに、送信プログラムを作成してみましたが、
マシン上にキューが存在していないように見えます。
([マイコンピュータの管理]-[サービスとアプリケーション]で
[Message Queuing]という項目が無い為)
コード: |
|
///
/// メッセージキューの送信プログラム
///
// メッセージキュー
String *strQue = S".\\private$\\Orders";
// テキスト メッセージを準備する
String *msgText;
msgText = String::Format(S"Sample Message Sent At {0}", DateTime::Now.ToString());
MessageQueue *msgQ;
// メッセージキューの存在チェック
if(!MessageQueue::Exists(strQue)){ // 存在しない場合
try{
msgQ = MessageQueue::Create(strQue);
}catch(Exception *e){
// コードにキューを作成するための十分な権限がなければ
// キューの作成時にエラーが発生する可能性がある
throw new Exception(S"Error Creating Queue", e);
}
}else{ // 存在していた場合
try{
msgQ = new MessageQueue(strQue);
}catch(Exception *e){
throw new Exception(S"Error Getting Queue", e);
}
}
// メッセージ送信
msgQ->Send(msgText, S"Sample Test");
|
|
- おばけ
- ぬし
- 会議室デビュー日: 2002/11/14
- 投稿数: 609
- お住まい・勤務地: 東京都江東区
|
投稿日時: 2004-02-03 16:10
私は.NETもWindowsアプリ開発も全然ですが、MSMQというのはMSが出しているメッセージキューの
ミドルウェアだと思います。この製品を入れないと件のAPIは機能しないでしょう。
|
- Jitta
- ぬし
- 会議室デビュー日: 2002/07/05
- 投稿数: 6267
- お住まい・勤務地: 兵庫県・海手
|
投稿日時: 2004-02-03 16:50
System.Messaging.dll を参照するようにして、System.Messaging 名前空間をインポート(C++はusingだっけ?)すれば、使えませんか?
|