tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルマップドファイルからメモリコピー
記事No10967
投稿日: 2012/11/28(Wed) 00:23
投稿者empty
いつもお世話になります。

c++にてマップドファイルを作成し、VB.netでメモリコピーし、データを確認(参照)する
といったことを行いたいのですが、VB.netにてメモリコピーがうまく行えません。

■環境
c++、VB.net(Visual Sutdio 2005)

■ソース
--------<c++>----------
//※eInfoは別関数にて値を代入しています
//仮として下記が格納されているとする
// eInfo.a = 11;
// eInfo.b = _T(test);


typedef    struct _SHARED_DATA
{
   int   a;
   char* b;
}SHARED_DATA;

bool test(SHARED_DATA* eInfo)
{

HANDLE m_hMapFile;          // メモリマップファイルハンドラ
SHARED_DATA* GLB_lpMapAddr; // 共有メモリアドレス

m_hMapFile = CreateFileMapping( (HANDLE)0xffffffff, NULL , PAGE_READWRITE | SEC_COMMIT ,
                     0 , 1024 , "ABC" );
GLB_lpMapAddr = (SHARED_DATA *)MapViewOfFile( m_hMapFile , FILE_MAP_WRITE , 0 , 0 , 0 );
memcpy(GLB_lpMapAddr,eInfo,sizeof(SHARED_DATA));
}

------------------------


--------<VB.net>----------
' ボタンを押すとマップドファイルの値を参照する
'

Private Sub cmdOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOK.Click
        Dim hFileMap As IntPtr
        Dim fMap As IntPtr
        Dim eInfo As SHARED_DATA

        hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, True, MAPPED_FILE_NAME)
    If hFileMap = 0 Then
            MsgBox("失敗")
            Return
        End If

    fMap = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0)
    'Call MoveMemory(eInfo, fMap, Len(eInfo))                  'ここがうまくいかない
    'eInfo = Marshal.PtrToStructure(fMap, GetType(SHARED_DATA))'ここがうまくいかない

        UnmapViewOfFile(fMap)
        CloseHandle(hFileMap)

}


#Region "OpenFileMapping定義"
    Declare Function OpenFileMapping Lib "kernel32" Alias "OpenFileMappingA" _
    (ByVal flProtect As UInt32, _
    ByVal flg As Boolean, _
    ByVal lpName As String) As Integer
#End Region

#Region "MapViewOfFile定義"
    Declare Function MapViewOfFile Lib "kernel32" ( _
    ByVal hFileMappingObject As IntPtr, _
    ByVal dwDesiredAccess As UInt32, _
    ByVal dwFileOffsetHigh As UInt32, _
    ByVal dwFileOffsetLow As UInt32, _
    ByVal dwNumberOfBytesToMap As UInt32) _
    As UInt32
#End Region

#Region "MoveMemory定義(Intptr→integer)"

    Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByVal Dest As String, _
    ByVal Source As IntPtr, _
    ByVal length As Integer)

#End Region
--------------------------

どうにかして、メモリ共有を使用し、
VB側で下記のデータを確認したいのですが、
どうしたらよいのでしょうか?
また、何が悪いのでしょうか?
// eInfo.a = 11;
// eInfo.b = _T(test);

勉強不足でお手間を取らせますが、お知恵をおかしください。

[ツリー表示へ]
タイトルRe: マップドファイルからメモリコピー
記事No10968
投稿日: 2012/11/28(Wed) 02:29
投稿者オショウ
> c++にてマップドファイルを作成し、VB.netでメモリコピーし、データを確認(参照)する
> といったことを行いたいのですが、VB.netにてメモリコピーがうまく行えません。

  とりあえず、こんなの見つけました。
  http://dobon.net/vb/bbs/log3-31/19304.html

以上。参考まで

[ツリー表示へ]
タイトルRe^2: マップドファイルからメモリコピー
記事No10969
投稿日: 2012/11/28(Wed) 09:53
投稿者empty


オショウさんありがとうございます。

> > c++にてマップドファイルを作成し、VB.netでメモリコピーし、データを確認(参照)する
> > といったことを行いたいのですが、VB.netにてメモリコピーがうまく行えません。
>
>   とりあえず、こんなの見つけました。
>   http://dobon.net/vb/bbs/log3-31/19304.html
>
> 以上。参考まで

参考URLは見てたんですが、構造体→構造体に執着しすぎて、Byteは試していませんでした。(・・;)

参考URLを使用し、MoveMemory、Marshal.PtrToStructureの部分を下記のように書き換えると、
>>// eInfo.a = 11;
の値をコピーできました。
------------------
------------------
Dim tBuf(1) As Byte
Marshal.Copy(fMap, tBuf, 0, 2)
------------------
結果:tBuf(0):11 tBuf(1):0
------------------
------------------

tBuf(1)についてですが、c++側では
>>// eInfo.b = _T(test);
と、文字を格納しています。

文字については"0"となってしまっています。
文字は参照できないのでしょうか?
(char* b としているのがまずい?)

検索はかけてみたのですが、見つけきれませんでした。
力不足でお手間を取らせますが、数値と文字を取得する方法を教えていただけませんでしょうか?

[ツリー表示へ]
タイトルRe^3: マップドファイルからメモリコピー
記事No10970
投稿日: 2012/11/28(Wed) 10:08
投稿者Hongliang
> typedef    struct _SHARED_DATA
> {
>    int   a;
>    char* b;
> }SHARED_DATA;

この構造体を

> memcpy(GLB_lpMapAddr,eInfo,sizeof(SHARED_DATA));

こうやっても、GLB_lpMapAdrに書き込まれるのはint型のaの値とchar*型のbの値(=ポインタ)だけで、
char*が指す先の文字列は書き込まれませんよ。
bを固定長配列にするなり、文字列はまた別に書き込むなりしないと。

[ツリー表示へ]
タイトルRe^4: マップドファイルからメモリコピー
記事No10971
投稿日: 2012/11/28(Wed) 11:14
投稿者empty
Hongliangさんありがとうございます。
下記のようにソースを書き換えたことで、文字を参照することができました。

[c++]--------------
> >    char* b;
char b[20];
-------------------

[vb.net]-----------
Dim a As String
Dim b(MemorySize - 1) As Byte
Marshal.Copy(fMap, tBuf, 0, MemorySize)
Buffer.BlockCopy(tBuf, 4, b, 0, 20)

a = System.Text.Encoding.GetEncoding("shift_jis").GetString(b)
-------------------

サイズを整えるとか、調整は必要ですが、文字を取得することができました。
オショウさん、Hongliangさんありがとうございます。

[ツリー表示へ]