- PR -

C言語とVB2005のプロセス間通信

1
投稿者投稿内容
平和主義?
会議室デビュー日: 2004/01/07
投稿数: 6
投稿日時: 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
----------------------------------------------------------------------
********************************************************************************


よろしくお願いいたします。
以上です。
ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2008-07-28 23:26
CreateFileMappingA なんての利用しているようですけど、C++ 側は当然 MBCS で build しているんですよね?

VC++ 2005 の default は Unicode build でっせ。
Unicode build されたものを扱うのであれば、CreateFileMappingW を使う必要があります。

それから、VB.NET で利用するという前提なら C++/CLI を使って VB.NET 側で楽できるように実装するのが筋じゃないかと思ったり。

Source は精査していないのであしからず。
平和主義?
会議室デビュー日: 2004/01/07
投稿数: 6
投稿日時: 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

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