- - PR -
C言語とVB2005のプロセス間通信
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2008-07-28 18:57
いつも拝見させて頂いております。
この度、壁にぶち当たってしまったので、皆さんのお知恵を拝借したく、投稿しました。 以下にコードを掲載しますので、おかしいところをご指摘ください。 開発環境 WindowsXP Pro SP3 .NET Framework Version 2.0.50727 SP1 Microsoft Visual C++ 2005 Express Microsoft Visual Basic 2005 Express やりたい事 ・VBアプリとCアプリのプロセス間通信(構造体単位でのデータ受渡し) ・データが大量にあり、リアルタイム処理が必要な為、プロセス間通信は共有メモリを採用 ・手始めにサンプルコード作成中 動作確認できている事 ・Cアプリ複数起動での、プロセス間通信確認 動作確認できていない事 ・VBアプリ複数起動での、プロセス間通信確認 ・CアプリとVBアプリ同時起動での、プロセス間通信確認 C側のコード ******************************************************************************** Main.cのコード ---------------------------------------------------------------------- #define MAPPED_FILE_NAME "MyMemory" typedef struct { int data0; int data1; int data2; } SHARED_DATA; int main() { HANDLE hMap; /* ファイルマッピングオブジェクトのハンドル */ SHARED_DATA CurrentData, *pData; /* 共有するデータ */ BOOL bAlreadyExists; char msg[1000]; /* ファイルマッピングオブジェクトの作成 */ hMap = CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,256, MAPPED_FILE_NAME); /* 既に作成されていた? */ bAlreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS); /* ビューの作成 */ pData = (SHARED_DATA *)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(SHARED_DATA)); /* 新規に作成された場合、共有データの初期化を行う */ if(!bAlreadyExists) { pData->data0 = 0; } /* 起動数のインクリメント */ pData->data0++; CurrentData = *pData; /* 結果の表示 */ wsprintf(msg, "起動数: %d", CurrentData.data0); MessageBox(NULL, msg, "Mapped File Test", MB_OK); /* 起動数のデクリメント */ pData->data0--; /* 後処理 */ UnmapViewOfFile(pData); CloseHandle(hMap); return(0); } ---------------------------------------------------------------------- ******************************************************************************** VB2005側のコード ******************************************************************************** Form1.vbのコード ---------------------------------------------------------------------- Option Strict On Option Explicit On Imports System.Runtime.InteropServices Public Class Form1 Private Const MAPPED_FILE_NAME As String = "MyMemory" Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim hMap As Integer 'ファイルマッピングオブジェクトのハンドル Dim SecurityAttribute As SECURITY_ATTRIBUTES Dim CurrentData As SHARED_DATA Dim pData As IntPtr '共有するデータ With SecurityAttribute .bInheritHandle = 0 '' ハンドルの継承しない。 .lpSecurityDescriptor = 0 '' セキュリティをセットしない。 .nLength = Len(SecurityAttribute) '' 構造体のサイズを設定 End With hMap = CreateFileMapping(&HFFFFFFFF, SecurityAttribute, PAGE_READWRITE, 0, 256, MAPPED_FILE_NAME) pData = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0) CopyMemory(CurrentData, pData, Len(CurrentData)) CurrentData.Data0 = CurrentData.Data0 + 1 MsgBox("起動数: " & CurrentData.Data0, MsgBoxStyle.OkOnly) CurrentData.Data0 = CurrentData.Data0 - 1 CopyMemory(pData, CurrentData, Len(CurrentData)) CloseHandle(hMap) UnmapViewOfFile(pData) End Sub End Class ---------------------------------------------------------------------- Module1.vbのコード ---------------------------------------------------------------------- Option Strict On Option Explicit On Imports System.Runtime.InteropServices Module Module1 <StructLayout(LayoutKind.Sequential)> _ Public Structure SHARED_DATA Dim Data0 As Integer Dim Data1 As Integer Dim Data2 As Integer End Structure <StructLayout(LayoutKind.Sequential)> _ Public Structure SECURITY_ATTRIBUTES Dim nLength As Integer '' 構造体の大きさ Dim lpSecurityDescriptor As Integer '' セキュリティ・ディスクリプタへのポインター Dim bInheritHandle As Integer '' ハンドルの継承設定 End Structure '' FILE_MAP_ALL_ACCESS 定数 Public Const PAGE_READWRITE As Integer = &H4S Public Const STANDARD_RIGHTS_REQUIRED As Integer = &HF0000 Public Const SECTION_QUERY As Integer = &H1S Public Const SECTION_MAP_WRITE As Integer = &H2S Public Const SECTION_MAP_READ As Integer = &H4S Public Const SECTION_MAP_EXECUTE As Integer = &H8S Public Const SECTION_EXTEND_SIZE As Integer = &H10S Public Const SECTION_ALL_ACCESS As Integer = STANDARD_RIGHTS_REQUIRED Or SECTION_QUERY Or SECTION_MAP_WRITE Or SECTION_MAP_READ Or SECTION_MAP_EXECUTE Or SECTION_EXTEND_SIZE Public Const FILE_MAP_ALL_ACCESS As Integer = SECTION_ALL_ACCESS '' 通常はこれを使用する。 <DllImport("kernel32", entrypoint:="CreateFileMappingA")> _ Public Function CreateFileMapping(ByVal hFile As Integer, ByRef lpFileMappigAttributes As SECURITY_ATTRIBUTES, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer End Function <DllImport("kernel32", entrypoint:="MapViewOfFile")> _ Public Function MapViewOfFile(ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As System.IntPtr End Function <DllImport("kernel32", entrypoint:="UnmapViewOfFile")> _ Public Function UnmapViewOfFile(ByRef lpBaseAddress As System.IntPtr) As Integer End Function <DllImport("kernel32", entrypoint:="RtlMoveMemory")> _ Public Function CloseHandle(ByVal hObject As Integer) As Integer End Function <DllImport("kernel32", entrypoint:="RtlMoveMemory")> _ Public Sub CopyMemory(ByRef Destination As SHARED_DATA, ByRef Source As System.IntPtr, ByVal Length As Integer) End Sub <DllImport("kernel32", entrypoint:="RtlMoveMemory")> _ Public Sub CopyMemory(ByRef Destination As System.IntPtr, ByRef Source As SHARED_DATA, ByVal Length As Integer) End Sub End Module ---------------------------------------------------------------------- ******************************************************************************** よろしくお願いいたします。 以上です。 |
|
投稿日時: 2008-07-28 23:26
CreateFileMappingA なんての利用しているようですけど、C++ 側は当然 MBCS で build しているんですよね?
VC++ 2005 の default は Unicode build でっせ。 Unicode build されたものを扱うのであれば、CreateFileMappingW を使う必要があります。 それから、VB.NET で利用するという前提なら C++/CLI を使って VB.NET 側で楽できるように実装するのが筋じゃないかと思ったり。 Source は精査していないのであしからず。 |
|
投稿日時: 2008-07-28 23:56
ちゃっぴ様、レスありがとうございます。
取り急ぎ、お礼まで。 > CreateFileMappingA なんての利用しているようですけど、C++ 側は当然 MBCS で build しているんですよね? > VC++ 2005 の default は Unicode build でっせ。 > Unicode build されたものを扱うのであれば、CreateFileMappingW を使う必要があります。 全然意識していませんでした。 確認します。 > それから、VB.NET で利用するという前提なら C++/CLI を使って VB.NET 側で楽できるように実装するのが筋じゃないかと思ったり。 C++/CLIという手段が選択肢にありませんでした。(VS2005は初心者なので・・・。) |
1