- PR -

DLL同士の通信

投稿者投稿内容
さらだ
会議室デビュー日: 2003/07/11
投稿数: 17
投稿日時: 2004-02-05 00:31
引用:

 SendMessageは、他の方の方が詳しそうだからパス(よろしく)


全然詳しくないのですが、書き込んだ手前補足しておきますと、SendMessageで
データを送るやり方は2つ見つけました。
1つは前述のWM_SETTEXTを指定する方法で、これは文字列データをウインドウの
タイトル文字として送信してやるという一種裏技的な方法ですね。
もう1つはWM_COPYDATAを指定する方法で、これを使えば文字列だけでなく、
バイナリデータ等任意のデータを渡せるようです。ただしこちらのほうは、データ
渡し用にメモリの確保をするのが、多少面倒そうです。
いずれにせよ、せっかくの.NETですから、APIを使わず.NET固有のやり方でできれば
いいんですけどね。
ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-02-05 08:31
引用:

Jittaさんの書き込み (2004-02-04 21:28) より:

セマフォは、そんな概念がない!!



実はあったりします…….NET FrameworkではなくWin32APIですが
CreateSemaphore
昔、プロセス間排他のために調べたことがありまして。
でも面倒そうだったのでSemaphoreは使う気になれず、Mutexばかり使いました(or使っている←System.Threading.Mutex)けど
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-05 09:01
みなさん、
いろんな情報、有難う御座います。

ひとつのやり方をとってみても、
どの場合に向いている、っていうのがあるのですねぇ。


Jittaさん、サンプルをありがとうございます。
早速、ソースを見て
C++のコードと照らし合わせながら試して
またご連絡いたします。

#風邪をひいたみたいで、
#昨日は返信できなくってすいませんでした(^^;)


[ メッセージ編集済み 編集者: 優希 編集日時 2004-02-05 09:11 ]
りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-05 09:46
こんにちわ。

引用:

ぢゃん♪さんの書き込み (2004-02-05 08:31) より:
引用:

Jittaさんの書き込み (2004-02-04 21:28) より:

セマフォは、そんな概念がない!!



実はあったりします…….NET FrameworkではなくWin32APIですが
CreateSemaphore
昔、プロセス間排他のために調べたことがありまして。
でも面倒そうだったのでSemaphoreは使う気になれず、Mutexばかり使いました(or使っている←System.Threading.Mutex)けど



関係ないですが(^^;MFCにもセマフォあります。
CSemaphoreです。

あと、Windowsフォームアプリってメッセージ扱えないのですか??
もしそうなら、なんて面倒な…
マウスクリックやらなにやらのメッセージも自分で処理できないのですか?
例えばMFCであればPreTranslateMessageあたりでいくらでもメッセージを
処理できるのに。
MFCアプリの場合、CWinThreadがメッセージポンプを持つので、ウィンドウを作れば
何も考えずSendMessage出来るのですが・・


あと、共有メモリですが、ぜんぜん難しくないと思うのですが?
単純な例でも。。。

コード:
HANDLE	hFileMap=NULL;
LPVOID	lpShareMem=NULL;
int*     piData;

// 共有メモリの作成部分
if((hFileMap=CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,
	0,sizeof(int),TEXT("SHAREMEM")))==NULL)
	return -1;
if((lpShareMem=MapViewOfFile(hFileMap_dat,FILE_MAP_READ | FILE_MAP_WRITE,
	0,0,0))==NULL)
	return -1;

// 共有メモリのリンク(使用する側)
if((hFileMap=OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE,
	FALSE,TEXT("SHAREMEM")))==NULL)
	return -1;
if((lpShareMem=MapViewOfFile(hFileMap_dat,FILE_MAP_READ | FILE_MAP_WRITE,
	0,0,0))==NULL)
	return -1;

// 共有メモリのアドレスをポインタ変数に格納
piData=(int*)lpShareMem;

// 共有メモリの開放(作成側、使用する側共通)
if(lpShareMem!=NULL)	UnmapViewOfFile((LPVOID)lpShareMem);
if(hFileMap!=NULL)		CloseHandle(hFileMap);



共有メモリの作成側と使用する側を一緒くたに書いてしまいましたが、
ご参考に^^;

[余談?]
結局、DLLはプロセスなのかそうでないのか・・・
プロセスとすると、DLLの関数をコールすると、その関数がプロセスとして
動くって事になりますよね?なんか変・・・

あと、GetModuleHandleじゃなくてもLoadLibraryでよいのでは^^;

ぼくも、猫でもわかるプログラミング、利用させて頂いてます・・
[/余談?]
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2004-02-05 11:32
ども、ほむらです。
-------
さらだ氏へ
引用:

もう1つはWM_COPYDATAを指定する方法で、これを使えば文字列だけでなく、
バイナリデータ等任意のデータを渡せるようです。ただしこちらのほうは、データ
渡し用にメモリの確保をするのが、多少面倒そうです。


こんなメッセージもあったんですね。
しかも便利そう。。。
メモリ確保に関しては送信用の関数を作ってしまえば何とかなりそうですね。
OLE使うかと思えばだいぶ楽そうですし。

ゆうじゅん氏へ
引用:

GetModuleHandleはプロセスに読み込まれたモジュールのモジュールハンドルを取得している
のであってプロセスハンドルじゃないですよ(読み込まれたメモリ上の位置)
なのでやっぱりnoderaさんの書き込みのようにDLL間通信というよりは読み込まれた
DLLの関数を直接使う方法を考えたほうがいいと思います。


プロセスハンドルというのを僕が誤解していたのかもしれませんが。。。
DLLで実行されるものは呼び出し元のプロセスとは別のプロセス空間だと思ったので
DLL=プロセスだと思っていました。
SDkで作れば実感ができるといったのは、
DLL_PROCESS_ATTACH(?)とDLL_THREAD_ATTACH(?)でわかれているからです。

>DLLの関数を直接使う方法を考えたほうがいいと思います。
DLLに情報を伝えるのならば関数経由とかでも良いのですが、
TLSの関係もあると思いますのでパラメータで渡すのもありかなと。。

引用:

SendMessageはいいと思うのですがこの場合送る先のウィンドウを特定するの
むずかしくないでしょうか?


後で考えたら難しいかもと思いましたが。。。
このときは親ウィンドウ経由を考えていました。
適当なメッセージを自分で作って親から子へ丸投げする形です。

りばぁ氏へ
メモリマップファイルは同期とか、開放がむずかしいとか、聞いていたのですけど
使い方はすごく簡単だったのですね。。。
同期取るだけなら難しくも無いような気がするし、僕も今度使ってみようかな〜

引用:

結局、DLLはプロセスなのかそうでないのか・・・
プロセスとすると、DLLの関数をコールすると、その関数がプロセスとして
動くって事になりますよね?なんか変・・・


たしかに、この辺は突っ込んでいくと難しそうですね。
DLLの関数がどこの空間で動いているのかとか今まで考えたこと無いですし。

>あと、GetModuleHandleじゃなくてもLoadLibraryでよいのでは^^;
LoadLibraryでも良いと思いますけど。参照カウントが増えてしまうので
ひと手間増えちゃいます。(.NETが暗黙的にロードしていると仮定)

#猫でもわかるプログラミング
#やっぱり知っている人はたくさんいるのですね。
#勉強にはもってこいですしね〜個人的にあれは買っても良いと思います。
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2004-02-05 14:13
引用:

ほむらさんの書き込み (2004-02-05 11:32) より:

プロセスハンドルというのを僕が誤解していたのかもしれませんが。。。
DLLで実行されるものは呼び出し元のプロセスとは別のプロセス空間だと思ったので
DLL=プロセスだと思っていました。
SDkで作れば実感ができるといったのは、
DLL_PROCESS_ATTACH(?)とDLL_THREAD_ATTACH(?)でわかれているからです。




GetModuleHandleでもLoadLibraryでも、呼び出し元とDLLは同一のプロセス空間内に展開されます。DLL=プロセスというのは、正確ではないと思います。

また、.NETには今までのプロセス、スレッドと共に、アプリケーションドメインという考えがあります。アプリケーションドメインは、ひとつのプロセス空間内で、さらにプロセス空間をいくつも作るような仕組みで(概念として)、通常アプリケーションドメイン間でデータ(メモリ)を干渉することはできません。もちろんプロセス間通信と同様にアプリケーションドメイン間での通信する手段も提供されていますが。

あと、揚げ足とりになってしまうかもしれませんが、「メモリマップファイル」ではなく「メモリマップト・ファイル」ですよね。。。。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2004-02-05 15:01
ども、ほむらです。
---------
nodera氏へ
引用:

GetModuleHandleでもLoadLibraryでも、呼び出し元とDLLは同一のプロセス空間内に展開されます。DLL=プロセスというのは、正確ではないと思います。


あっそうだったんですか〜
今まで別だと思っていたのでヒープ使ったことないのですけど
実は使っても問題なかったんですね。

DLL=別プロセスは間違いのようですね。

引用:

また、.NETには今までのプロセス、スレッドと共に、アプリケーションドメインという考えがあります。アプリケーションドメインは、ひとつのプロセス空間内で、さらにプロセス空間をいくつも作るような仕組みで(概念として)、通常アプリケーションドメイン間でデータ(メモリ)を干渉することはできません。もちろんプロセス間通信と同様にアプリケーションドメイン間での通信する手段も提供されていますが。


ほほう。
.NETになるとがらりと変わるんですね。
VC6の時代の作り方ができるのもあと2年くらいか。。
やっぱり、Windows系の仕事やろうと思ったら.NETやんなきゃだめっぽいですね。
も、もうおそいかな?

>「メモリマップファイル」ではなく
日本人に言わせるといろいろな言い方になりますよね^^;;;;
たぶんメモリマップドが正しいのかもと思いますけど。
なんかゴロがあまり好きじゃないです(笑

#以下追記
#読み返してみるとかなり無茶な考え方していることに気が付いた^^;;;;
#プロセス空間が違っていたら、データのやり取りできないっすよね(笑

[ メッセージ編集済み 編集者: ほむら 編集日時 2004-02-05 15:16 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-05 18:18
引用:

りばぁさんの書き込み (2004-02-05 09:46) より:

関係ないですが(^^;MFCにもセマフォあります。
CSemaphoreです。


 探し方が悪かったようで。。。いや、昔のことだから、日本語で探そうとしていたのが間違いだったのかも。


> あと、共有メモリですが、ぜんぜん難しくないと思うのですが?
> 単純な例でも。。。
 なんというか、1年半使わないでいると、C++の文法を忘れています。あはは .NETからC++のDLLを呼び出すのも、1年前には使っているのに、使ったプログラムが存在しているのに、忘れている。。。年齢のせいにしていいのだろうか?


> [余談?]
> 結局、DLLはプロセスなのかそうでないのか・・・
> プロセスとすると、DLLの関数をコールすると、
> その関数がプロセスとして動くって事になりますよね?なんか変・・・
 プロセス=「経過; 過程; 手順, 方法, 工程;」(EXCEED英和辞典)なので、一つ一つの命令がプロセスであり、処理全体もより大きな処理の過程なのでプロセスであり、、、ってところですね。実行形式というプロセスの中に含まれるプロセス・・・.NETで「アプリケーションドメイン」という概念を導入したのは、そういう思考の無限ループを回避するためなのでしょうか?

スキルアップ/キャリアアップ(JOB@IT)