tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルクラスライブラリを解してのプロセス間データ共有
記事No6213
投稿日: 2007/09/01(Sat) 23:24
投稿者キジ
VB2005(SP1) .NET Framwork2.0です。
掲題のように、クラスライブラリを解してのVB2005で作成した2つのプロセス
(仮称Task1、Task2)の間で構造体のデータを共有させたいと試行錯誤しています。
手段として、マッピングファイルを使用しています。


<Serializable()> Public NotInheritable Class SharedMemory
        ・
        ・
        ・
    Structure ShmArea
        Dim intNo As Integer
    End Structure
    Public mstShmArea As New ShmArea
    Private m_address As IntPtr
        ・
        ・
        ・
    Public Sub New(ByVal strMAPFILENAME As String)

        m_hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, False, strMAPFILENAME)

        If m_hFileMap.Equals(IntPtr.Zero) Then
            Call MsgBox("Create!")
            m_hFileMap = CreateFileMapping(InvalidHandleValue, _
               IntPtr.Zero, PAGE_READWRITE, 0, Len(mstShmArea), strMAPFILENAME)
        End If

        If (m_hFileMap.Equals(IntPtr.Zero)) Then
            Call MsgBox("Error1")
        Else
            m_address = MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, IntPtr.Zero)
        End If

        If (m_address.Equals(IntPtr.Zero)) Then
            Call MsgBox("Error2")
        Else
            CopyMemory(mstShmArea, m_address, Len(mstShmArea))
            'mstShmArea = Marshal.PtrToStructure(m_address, GetType(ShmArea))
            'mstShmArea = CType(Marshal.PtrToStructure(m_address, GetType(ShmArea)), ShmArea)
        End If
    End Sub
End Class



mstShmAreaを共有しようとしています。
マッピングファイル自体の共有といいいますか、オープンはうまくいっているようなのですが
Task1で書き込んだ値がTask2で読み込めていません。
Task2でmstShmArea.intNoは常に0です。Task1で自分が書き込んで読み返したのは
ネットで調べて、マッピングファイルのアドレスを構造体に渡す方法を
CopyMemoryやMarshal.PtrToStructureで試したりしましたがどれもうまくいきません。

取得したm_addressを構造体に渡す方法、もしくはマッピングファイル以外で
プロセス間でデータ共有できる方法をご教示いただきたく、お願いいたします。

[ツリー表示へ]
タイトルRe: クラスライブラリを解してのプロセス間データ共有
記事No6214
投稿日: 2007/09/03(Mon) 02:47
投稿者魔界の仮面弁士
> プロセス間でデータ共有できる方法

".NET Remoting" とか…。

[ツリー表示へ]
タイトルRe^2: クラスライブラリを解してのプロセス間データ共有
記事No6221
投稿日: 2007/09/03(Mon) 18:27
投稿者キジ
> > プロセス間でデータ共有できる方法
>
> ".NET Remoting" とか…。


まず本文訂正させてください。
「Task1で自分が書き込んで読み返したのは・・・」の続きを書き忘れていました。
「Task1で自分が書き込んで読み返したのは、うまくいっています」です。

魔界の仮面弁士 さんありがとうございます。
リモーティングですか・・・。
これも以前からちょっとテストしたりしてましたが、あまり手軽そうでもないし
知人から今後残る技術かどうか疑問(←これ本当ですかね?)との意見もあり躊躇しております。



すこし分かってきたような気がします。
Marshal.PtrToStructureやStructureToPtrについて誤解しているような気がしてきました。
MarshalというのはC言語でいうところの
    pAdr = MapViewOfFile(hMemMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(ShmArea));
としたとき、
    stpShm = (ShmArea *)pAdr;    //(stpShmはShmArea構造体の変数ポインタ)
ではなく
    memcpy(stpShm, pAdr, sizeof(ShmArea));
ではないでしょうか?
これだと、共有構造体にデータを読み書きする都度PtrToStructureやStructureToPtrで
共有ポインタpAdrからデータをコピーしてきてやらないといけませんよね。
よしんばそれを行ったとしても構造体ということから、あるメンバ1つに書き込みするのに、
pAdrという先頭アドレスから構造体全部を書き込むと、
他プロセスから書いた他のメンバのデータまでもが上書きされちゃいますよね。
なら毎回pAdrから目的のメンバのオフセットポインタを割り出しますか・・・?


VB2005にて上記の
stpShm = (ShmArea *)pAdr;
のようなアドレス渡しってできないんでしょうか?
色々調べましたが、どうしてもMarshal関係しか出て来ません。

[ツリー表示へ]
タイトルRe^3: クラスライブラリを解してのプロセス間データ共有
記事No6227
投稿日: 2007/09/04(Tue) 09:55
投稿者キジ
自己レスです。
VBにはポインタ変数がないから、やはり実現不可なんでしょうね。
ポインタの代入をVCのDLLで代用するため
__declspec(dllexport) void APIENTRY Pointer2Pointer(long *pDsc, long *pSrc)
{
    pDsc = pSrc;
}

とかやってみましたが、

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
PInvokeStackImbalance が検出されました。
Message: PInvoke 関数 'WindowsApplication1!WindowsApplication1.mdlApsShared::Pointer2Pointer' がスタックを不安定にしています。PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。呼び出し規約、および PInvoke シグネチャのパラメータがターゲットのアンマネージ シグネチャに一致していることを確認してください。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

となりました。
pDscは結局VBのデータ変数(ポインタ変数ではない)なのでメモリ破壊と見なされるんでしょうね。

あきらめて従来どおり、全てVCのDLLで作成し、その中でデータ共有することにします。

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

[ツリー表示へ]