• ベストアンサー

MapViewOfFile() はカウンタを進めない?

Windows APIの質問です。 PINT GetShareInt() { ____HANDLE hmap = CreateFileMapping( ________INVALID_HANDLE_VALUE, NULL, ________PAGE_READWRITE, ________0, sizeof(int), ________TEXT("Share") ); ____PINT pi = (PINT)MapViewOfFile( ________hmap, FILE_MAP_WRITE, 0, 0, 0); ____CloseHandle(hmap); ____return pi; } こんな感じの関数で変数をプロセス間共有したいのですが、 ファイルマッピングオブジェクトが毎回生成されてしまい、 変数を共有できません。 先にCloseHandleするのは後の処理がUnmapViewOfFileするだけで すむからです。変則的ですが、MapViewOfFile呼び出ししている以上 hmapが指すカーネルオブジェクトは開放されないと思うのですが。 MapViewOfFileがカーネルオブジェクトの内部カウンタを進めていない、 ということでしょうか?それではマルチスレッドで扱えないような気が するのですが、私の認識のどこが間違っているのでしょうか? よろしくご指導お願い申し上げます。

質問者が選んだベストアンサー

  • ベストアンサー
  • nitscape
  • ベストアンサー率30% (275/909)
回答No.5

#1です。 >クラスオブジェクトのデストラクタとUnmapViewOfFileの機能は違いますよね。 >スマートポインタと言うんでしょうか? 正式な用語で言うところの「スマートポインタ」とは別物ですが、考え方は同じです。 もちろんオブジェクトのデストラクタとUnmapViewOfFileの機能は全然違うものです。しかしデストラクタでUnmapViewOfFileやCloseHandleを呼び出すようにしておけば、Closeし忘れていても自動的に開放されるというわけです。 >次のようにするとマッピングオブジェクトは共有さ>れるようです。 >PVOID GetMem() { >----HANDLE hMap = CreateFileMapping(... >----DWORD dwEroor = GetlastError(); >----PVOIE pMem = MapViewOfFle(... >----if (dwError) CloseHandle(hMap); >----return pMem; >} この場合は2度目の呼び出しのときはCloseHandleが実行されますが、1度目のときは実行されない(dwError==0となる)ので開放し忘れに気をつける必要があると思います。この方法で共有できるようですがやはりMicrososftが意図している通りの順序(Create、Map、Unmap、Close)で使用したほうがいいと思います。 >「共有の制約」とは何のことでしょうか? >また、今回はページングファイルに支持されたメモリマップドファイルですから例外かもしれません。 確かに考えてみたらまったく関係がないかもしれません。すみません。共有の制約というのはhFileのshare属性のように思えますので。 http://www.microsoft.com/japan/msdn/library/ja/jpmemory/html/_win32_unmapviewoffile.asp

yak3141
質問者

お礼

ご返答ありがとうございます。 単純なデストラクタとCloseHandleのやっていることとは違う、ということを言いたかったんですが、釈迦に説法のようなことをしてしまい、赤面の至りです。 msdnの関数説明のところに書いてあったんですね。文書番号や「共有の制約」などで見当違いな検索をしていました。 >1度目のときは実行されない(dwError==0となる)ので開放し忘れに気をつける必要があると思います 理解しております。今回はシステムフックするDLLにコーディングしています。つまり最初に読み込むプロセスがフックの所有者であるため、このプロセスで解放する必要がないということで前述のコードにしたわけです。 >やはりMicrososftが意図している通りの順序(Create、Map、Unmap、Close)で使用したほうがいいと思います これについてはもちろん同意します。現在のOSで動くからといってもドキュメントされていない以上、仕様はいつ変更されるかわかりませんよね。(Microsoftは極力、動作互換性を重視してくれるとは思いますが) SDKを使う際にはメカニズムがどうなっているのかイメージしておきたいという気持ちがありますので、他人には理解されない質問かも、と思っていました。しかし数々のアドバイスをいただき、私なりに大変勉強になりました。 ご回答本当にありがとうございました。

その他の回答 (4)

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.4

ファイルマッピングとCloseHandleとはそういうものなのだと思います。 プロセスAでCreateFileMapping(..., TEXT("Share")); プロセスAでCloseHandle プロセスBでCreateFileMapping(..., TEXT("Share")); プロセスBでCloseHandle としたときに、プロセスBが新しいファイルマッピングオブジェクトを作るのは自然なことに思われます。 >MapViewOfFile呼び出ししている以上 >hmapが指すカーネルオブジェクトは開放されないと思うのですが。 「ユーザは全ハンドルを解放したが、マップトファイルが参照している」という状態で残るのかも… 解決策は、CloseHandleしない、というのが一番いいと思われます…

yak3141
質問者

お礼

私も同じ結論を仮定していました。 「ユーザはマップトファイルの全ハンドルを解放したが、最低ひとつのビューが参照している状態」ではマップトファイルは解放されていないが取得することはできない。 そういうことだと思います。 kmb01さん、回答ありがとうございました。

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.3

#1です。補足になります。 MSDNではUnmapViewOfFileについて ---------------------- •Windows 95:1 つのファイルの最後のビューがまだアンマップされていない場合、そのファイルは引き続き開いていて、元のファイルハンドルと同じ共有の制約が適用されます。 •Windows NT/2000:1 つのファイルの最後のビューがまだアンマップされていない場合、そのファイルは引き続き開いていますが、共有の制約は適用されません。 ---------------------- とありました。つまり、Win9x系ではyak3141さんの意図する通りに動作するのかもしれません。

yak3141
質問者

お礼

下の回答も含めてご返事が送れました。本当に丁寧な回答ありがとうございます。 「共有の制約」とは何のことでしょうか? セキュリティフラグあるいはビューの読み書きモードのことですかね? また、今回はページングファイルに支持されたメモリマップドファイルですから例外かもしれません。 msdnを早速探してみましたが目的の文書は見つけることはできませんでした。よろしければリンクを教えていただけないでしょうか? 回答のお礼が遅れた上でのあつかましいお願いですが、よろしければもう少しお付き合いくださいませ。

yak3141
質問者

補足

次のようにするとマッピングオブジェクトは共有されるようです。 PVOID GetMem() { ----HANDLE hMap = CreateFileMapping(... ----DWORD dwEroor = GetlastError(); ----PVOIE pMem = MapViewOfFle(... ----if (dwError) CloseHandle(hMap); ----return pMem; }

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.2

#1です。 >なぜ先にCloseHandleしてはいけないのでしょうか? >こだわるのは >1.解放忘れがない >2.ひとつの変数だけ保持しておけばよいので楽 >というメリットがあるからなのですが、それだけで 詳しいメカニズムについて私は知りませんが。。。普通のメモリに例えるとおそらく以下のようになっているのではないでしょうか? BYTE* pszBuff; char* pCopy; pszBuff = new BYTE[10];  //メモリ確保 pCopy = (char*)pszBuff;  //アドレス取得 delete pszBuff;      //メモリ開放忘れがないように先にdelete strcpy(pCopy,"asss");   //取得したアドレスだから使えるはずだけど。。。 開放忘れを防ぎたいというのでしたら、以下のようなクラスを作成すればいいかと思います。 class CFileMapping { HANDLE _hMap; HANDLE _hMem; public: CFileMapping(){_hMap = NULL;_hMem = NULL;} ~CFileMapping() { Unmap(); Close(); } void Unmap() { if(_hMem) UnmapViewOfFile(_hMem); _hMem = NULL; } void Close() { if(_hMap) CloseHandle(_hMap); _hMap = NULL; } 。。。。。そのたCreateFileMappingやMapViewなどをする関数を用意 };

yak3141
質問者

お礼

再回答ありがとうございます。 クラスオブジェクトのデストラクタとUnmapViewOfFileの機能は違いますよね。スマートポインタと言うんでしょうか?

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.1

>先にCloseHandleするのは後の処理がUnmapViewOfFileするだけですむからです。 これが原因ではないでしょうか? 普通は ----------------- hMap = CreateFileMapping() pMem = MapViewOfFile() 処理 UnmapViewOfFile (pMem); CloseHandle(hMap); ----------------- のように使うかと思います。

yak3141
質問者

お礼

早速の回答ありがとうございます。 質問でも述べさせていただきましたが、 なぜ先にCloseHandleしてはいけないのでしょうか? こだわるのは 1.解放忘れがない 2.ひとつの変数だけ保持しておけばよいので楽 というメリットがあるからなのですが、それだけではなく 「MapViewOfFileした後なのに、CloseHandleするとマッピングオブジェクトが解放されてしまう」という現象をなぜそうなるのかメカニズムを知りたいと思い、質問させていただきました。 nitscapeさん、回答ありがとうございました。

関連するQ&A

  • 共有メモリへのマッピング(MapViewOfFile)について

    共有メモリについて(特にMapViewOffileについて)教えてください。 ある構造体と、あるデータAを共有メモリへマッピングしたい考えています。 構造体は、 typedef struct _Data { int length; long data; char mIntArrayData[256]; } Data; データAは、short型の配列(要素数はx*y*z,x,y,zはcsvファイル等から読み込む)で、サイズをdatasize = sizeof(short) * x * y * z;とします。 この2つを使って、 両方のデータを long AllDataSize = sizeof(Data) + datasizeとしました。 このサイズを使って、共有メモリのマップハンドルを hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,PAGE_READWRITE,AllDataSize,MAPPED_FILE_NAME); (MAPPED_FILE_NAMEは、 メモリマップドファイルの名前) で、生成しました。 生成はできたのですが、データAにアクセスするための下記のような時にマッピングに失敗してしまいました。 DWORD dwOffset = sizeof(DATA); short *pData = (short *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, dwOffset, Bytes); (Bytesはマッピングしたいバイト数でsizeof(short)の倍数) 次のようなDATAにアクセスするマッピングには成功しています。 DWORD dwOffset = 0; DATA *pDATA = (DATA *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, dwOffset, sizeof(DATA)); 色々なサイト等を調べて、考えてみたのですが、怪しいところはdwOffsetと、CreateFileMappingで、マッピングしたい全体のファイルサイズを、構造体とデータAのサイズの単純な足し算としているところと考えています。ただ、はっきりとした答えが全くわからないので、どうか御教授お願いします。

  • 【C++】セマフォとプロセスの使い方

    【C++】セマフォとプロセスの使い方 WindowsXPでVC++2008コンパイラを使用して、 プロセスとセマフォについて勉強しています。 外部プログラム(今回は電卓として)を5つ立ち上げるのですが、 同時に立ち上げるのは2つまでとしたい場合、どのように組むのでしょうか。 http://nienie.com/~masapico/api_CreateSemaphore.html こちらにスレッドを使用したセマフォを使ったサンプルがあるのでが、 プロセスを使うとなると、うまく書けません。 ご指導頂けませんでしょうか。 ===現在まで書いたソース=== (5つのプロセスをつくるループも実装していませんが、、、) #include<windows.h> #include<stdio.h> #include<tchar.h> HANDLE g_hSemaphre; void main(){ BOOL bRet; STARTUPINFO si; PROCESS_INFORMATION pi; //Semaphoreオブジェクト g_hSemaphre = CreateSemaphore(NULL,2,2,NULL); bRet = CreateProcess(_T("C:\\WINDOWS\\system32\\calc.exe"), _T(""), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); //プロセス終了 WaitForSingleObject(pi.hProcess,INFINITE); //後処理(プロセス開放) ReleaseSemaphore(g_hSemaphre,1,NULL); //スレッドとプロセスを閉じる。 CloseHandle(pi.hThread); CloseHandle(pi.hProcess); //Semaphoreオブジェクト CloseHandle(g_hSemaphre); }

  • CreateFileMapping について

    CreateFileMapping を使用し アプリケーション間のデータ共有プログラムを作成しています。 CreateFileMapping には構造体を登録し その構造体で 文字列配列を動的に確保したいのですが // 構造体 typedef struct {   char **huga; } HOGE; main ---------------------------------- // マップ map = CreateFileMapping(   (HANDLE)0xffffffff,   NULL,   PAGE_READWRITE | SEC_COMMIT,   0, sizeof(HOGE),   "MAP_NAME"); // ビュー data = ( HOGE * )MapViewOfFile( map, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(HOGE) ); // 初回 flag = ( GetLastError() == ERROR_ALREADY_EXISTS ); if ( !flag ) {   // 確保 1   data->huga = new char*[ 10 ];   for ( int i = 0; i < 10; i++ ) {     // 確保 2     data->huga[ i ] = new char[ 256 ]; sprintf_s( data->huga[ i ], 256, "[ %d ]", i );   } } // 確認 for ( int i = 0; i < 10; i++ ) {   MessageBox( NULL, data->huga[ i ], "MAP", MB_OK ); } 上記のようにすると 確保する前の構造体が Mappingされているのか データを共有することが出来ませんでした。 動的確保した文字列配列を共有するには どのように設計すれば宜しいでしょうか。 よろしくお願いします。

  • CreateProcessでアプリが終了しない

    ちょっとした変換ツールを作ろうと思い、ダイアログベースの MFCアプリケーションを作成しました。 OKボタンが押された時にCreateProcess()で子プロセスを 起動して、終了したら結果表示して親プロセスも終了する 様にしようと思ったのですが、結果表示までは正常に 実行されるのですが、親プロセスが終了しません。 恐らくCreateProcess()に渡す引数が悪いのだと思うのですが、 どなたかわかる方がいらしたらご教示願います。 void CMscGenSelectorDlg::OnBnClickedOk() {   STARTUPINFO si;   PROCESS_INFORMATION pi;   ZeroMemory( &si, sizeof si );   si.cb = sizeof si;   ZeroMemory( &pi, sizeof pi );   // 子プロセス起動   CreateProcess(     NULL,                // モジュール名     _T("mscgen.exe -Tpng hoge.msc"),  // コマンドライン     NULL,                // セキュリティ記述子     NULL,                // セキュリティ記述子     FALSE,               // ハンドルの継承オプション     0,                 // 作成のフラグ     NULL,                // 新しい環境ブロック     NULL,                // カレントディレクトリ名     &si,                // スタートアップ情報     &pi);                // プロセス情報   // 子プロセス終了待ち   WaitForSingleObject( pi.hProcess, INFINITE );   CloseHandle( pi.hProcess );   CloseHandle( pi.hThread );   // シーケンスチャート表示   ShellExecute( NULL, _T("open"), _T("hoge.png"), NULL, NULL, SW_SHOW );   // 終了   OnOK(); }

  • ATL CWorkerThread

    初歩的な質問で申し訳ないですが、ATLにおけるCWorkerThreadを使ってマルチスレッドプログラミングをしたいのですが、情報が少なく、msdnを見てもサンプルが無いようなので利用法がいまいちわかりません。 どなたか簡単なサンプルでもよいので教えていただけないでしょうか。 具体的には、以下の解説 http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclib/html/vclrfcworkerthread.asp ----------------------------------------- CWorkerThread クラスを使用するには 1. このクラスのインスタンスを作成します。 2. CWorkerThread::Initialize を呼び出します。 3. CWorkerThread::AddHandle を、カーネル オブジェクトのハンドルと、IWorkerThreadClient の実装へのポインタを指定して呼び出します。 または CWorkerThread::AddTimer を IWorkerThreadClient の実装へのポインタを指定して呼び出します。 4. IWorkerThreadClient::Execute を実装し、ハンドルまたはタイマがシグナルを送信したときにアクションを実行します。 5. CWorkerThread::RemoveHandle を呼び出して、待機可能オブジェクトのリストからオブジェクトを削除します。 6. CWorkerThread::Shutdown を呼び出して、スレッドを終了します。 ------------------------ の3の、カーネル オブジェクトのハンドルが何かがよくわかりません。AddHandleに何のHANDLEを渡せばよいかで躓いています。

  • Delphi6 DLL内でのメモリ共有(?)

    こんにちは、honiyonです。  複数アプリケーションからそれぞれコールバック関数を登録してもらい、状況に応じてそれぞれのコールバック関数を呼び出す、というDLLを作成しています。  しかし現在、呼び出しアプリケーションごとにメモリ空間が独立してしまい、コールバック情報を同一空間内で管理出来ずに困っています。  旧VerのDelphiで16bit DLLなら、interface部に定義した変数、オブジェクトはDLL内で同一空間内で共有出来るようですが、これをDelphi6 32bitDLLで行う事は不可能でしょうか? もしくは、その他の方法で独立メモリ空間を作らないようにする方法はありますでしょうか?  不可能な場合、CreateFileMappingが次に有効な手段として候補に挙がると思います。CreateFileMappingで管理クラスのポインタを渡してクラス共有というのは現実的な手法でしょうか?  よろしくお願いいます(..

  • アプリケーション起動について

    ひろと申します。 クライアントからサーバの共有フォルダにある、他のアプリケーションを オプション付きで起動させるプログラムをVC++で作成したのですが、 クライアントがNTだとうまくいきません。 たとえば、サーバ上にあるapp.exeを「app.exe /i」のような感じで 起動すると、クライアントがwin98の場合はアプリケーションが 表示されるのですが、NTから起動させようとすると、 アプリケーションは表示されません。 また、オプションを外すとアプリケーションは NTでも表示されます。 APIは、WinExec,ShellExecuteEx,CreateProcessで試したのですが 同じ結果でした。 CreateProcess は以下のように設定してます。 ------------------------------------------------------------------ STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; CreateProcess(NULL, "serverpath\\app.exe /i", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); プロセスの起動は成功していうようです。 クライアントがNTの場合、他に必要な設定があるのでしょうか? よろしくお願いします。

  • マルチスレッドプログラミングについて

    マルチスレッドプログラミングについていくつか教えて下さい。 マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。 1:イベントオブジェクトについて教えて下さい。 「イベントオブジェクト」の概念がよく分かりません。 ○シグナル状態と非シグナル状態とはどういう状態なのでしょうか? ○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合) ○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合) 2:CloseHandle() と ExitThread() について教えて下さい。 ○この2つの関数の役割の違いについて教えて下さい。 「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか? また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?) 下記のソースは簡略化のためかなり省略されています。 DWORD WINAPI ThreadProc( DWORD i ) { while( true ) { DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ); if( r == WAIT_OBJECT_0 ) { // 処理1 } else if( r == WAIT_OBJECT_0 ) { // 処理2 } else { ExitThread( TRUE ); // スレッド終了 } } } void MainProc() { // 自動リセットのイベントオブジェクト作成 for( int i=0; i<2; i++ ) { hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); } // スレッドを作成 hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID ); }

  • CreateProcessでうまくexeファイルの起動ができません。

    Win32APIでファイルを読み込むプログラムとCreateProcessによる別に作った、OpenCVの2値化動画像の特徴点抽出をして得られた特徴点の座標を保存するプログラムを起動させるプログラムなのですが、起動はできても特徴点の座標取得ができません。外部起動せずにOpenCVのプログラムを動かすと座標がテキストファイルに保存されます。原因が分からないので、分かる方どなたかご教授願います。 環境はWindowsXP Visual C++ 2008 Express Editionです。 以下がWindowsプログラミングのソースの一部です。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { STARTUPINFO si; PROCESS_INFORMATION pi; DWORD dwExCode; FILE *fp; errno_t err; TCHAR buf[10]; TCHAR *temp; TCHAR cmdstr[] = _T("C:\\Documents and Settings\\m22015\\My Documents\\Visual Studio 2008\\Projects\\capflow\\Debug\\capflow.exe"); switch(msg){ case WM_CREATE: ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); si.cb = sizeof(si); if(!CreateProcess(NULL, cmdstr, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,NULL, NULL, &si, &pi)){ MessageBox(hWnd, TEXT("Can't open capflow.exe"), TEXT("Error"), MB_OK); } while(1){ Sleep(100); GetExitCodeProcess(pi.hProcess, &dwExCode); if(dwExCode == STILL_ACTIVE){ continue; }else{ MessageBox(hWnd, TEXT("Finish"), TEXT("Complete"), MB_OK); break; } } CloseHandle(pi.hProcess); WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hThread); break; case WM_KEYUP: switch(LOWORD(wParam)){ case VK_RETURN: err = _tfopen_s(&fp, TEXT("C:\\Documents and Settings\\m22015\\My Documents\\Visual Studio 2008\\Projects\\capflow\\Debug\\Corner.txt"), TEXT("r+")); if(err != 0) break; temp = (TCHAR*)malloc(_tcsclen(buf)+1); if(temp == NULL){ MessageBox(hWnd, TEXT("Can't secure of memory"), TEXT("Error"), MB_OK); break; } while(_fgetts(buf, 10, fp) != NULL){ _tcstok(buf, TEXT("\n")); _tcscpy(temp, buf); MessageBox(hWnd, temp, TEXT("Indication"), MB_OK); } free(temp); fclose(fp); break; } break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wParam, lParam)); } return 0; }

  • [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クラスはソースが隠蔽されていて、わかりませんが、 何かアドバイスいただけませんでしょうか。よろしくお願いします。

専門家に質問してみよう