こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

[C#][FX]DLLを利用した共有メモリの動作

こんにちわ。
外国為替取引のFXに利用するプログラムを作成しています。
その中で、
C#のプログラムAと
MQLという言語によるプログラムBにおいて、
共有メモリ読み書きを行うDLLを利用して、
(1)Aの結果を共有メモリに書き込み→Bで受け取って処理。
(2)Bの結果を共有メモリに書き込み→Aで受け取って処理。
という仕組みを作成しています。
(2)はできたのですが、(1)がうまくいきません。
知見をお持ちの方アドバイスいただけませんでしょうか。
以下詳細でございます。

●相談内容
共有メモリ書き込み時に以下エラーが発生し、書き込みができない。
「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」

●ソース(一部抜粋。InitializeとRunは基盤システムからコールされます。)
【C#ソース】
using System.Runtime.InteropServices;
using System;

[DllImport("MemMap.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern string SetMemString(string tag, string msg);

public bool Initialize()
{
try{
Console.Write("try01");
SetMemString("TEST", "1");
Console.Write("try02");
SetMemMethod();
}catch(Exception e){
Console.Write(e.Message);
Console.Write(e.StackTrace);
}
return true;
}

public void SetMemMethod(){
SetMemString("TEST", "2");
}

public void Run(){
try{
Console.Write("try03");
SetMemString("TEST", "3");
}catch(Exception e){
Console.Write(e.Message);
Console.Write(e.StackTrace);
}
}
}
}

【コンソール】
try01
保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。
場所 test.Main.SetMemString(String tag, String msg)
場所 test.Main.Initialize()
try03
保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。
場所 test.Main.SetMemString(String tag, String msg)
場所 test.Main.Run(

【DLL】
MT4_EXPFUNC const char* __stdcall SetMemString(char *tag,char *msg)
{
/*static*/ string ret = "";
bool create = false;
HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, tag);
if (!hMap) {
hMap= CreateFileMapping((HANDLE)0xFFFFFFFF , NULL ,
PAGE_READWRITE , 0 , 1024 , tag);
q.push(hMap);
create = true;
}
LPSTR strAllCmd =(LPSTR)MapViewOfFile(hMap , FILE_MAP_WRITE , 0 , 0 , 0);
lstrcpy(strAllCmd , msg);
FlushViewOfFile(strAllCmd,0);
UnmapViewOfFile(strAllCmd);
if(!create) CloseHandle(hMap);
return(ret.c_str());
}

●詳細
try01直後の初期化メソッド(Initialize)で直接コールするSetMemStringは問題なく出来ており、プログラムB側で読むことができていますが、
try02直後の初期化メソッド(Initialize)でコールするメソッドの中のSetMemStringと
try03直後のメイン処理(Run)の中のSetMemString
でエラーが発生します。

try02はソースの綺麗さを保つために別メソッドに切り出したいだけなので、
最悪初期化メソッドに直書きすればよいですが、
メイン処理なので、try03でエラーが発生するのはなんとしても解決したいです。

try01で呼べていることからDllImportのスコープがうまくできていないのでは?
と考えています。
継承元のExpertクラスはソースが隠蔽されていて、わかりませんが、
何かアドバイスいただけませんでしょうか。よろしくお願いします。

投稿日時 - 2014-11-24 16:09:28

QNo.8835743

困ってます

このQ&Aは役に立ちましたか?

14人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

呼び出し流れが良くわかりませんが、SetMemString を繰り返すならば 少なくとも UnmapViewOfFile は1度にしておいた方が良いと思いますが...

投稿日時 - 2014-11-24 18:36:21

補足

アドバイスありがとうございます。
DLLはネットにあったものを拾ってきただけなので、詳しくわからないのですが、
DLLの
>>UnmapViewOfFile(strAllCmd);
という行を削除し、
初期化時点でUnmapViewOfFile を1回だけ呼ぶ方がよいということでしょうか。
そうすることで、エラーは解消されそうですか。

投稿日時 - 2014-11-24 20:12:24

あなたにオススメの質問