1

アンマネージ dll (c++ および WinAPI を使用) を作成していますが、いくつかの C# メソッドを使用したいので、C++/CLI を使用してラッパーを作成しました。

しかし、問題は次のとおりです。管理されていない dll が「注入」され (LoadLibrary)、Wrapper 関数を呼び出す方法がわからないまま、ここで立ち往生しています。

アンマネージ コード:

#include <Windows.h>

//the function I want to call
__declspec(dllexport) void SimpleTest(int *p);

extern "C" __declspec(dllexport) void MyEntryPoint()
{
    int* test;
    SimpleTest(test);
}

BOOL WINAPI DllMain(/*DllMain parameters*/)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            MyEntryPoint();
            break;
    }

    return TRUE;
}

ラッパー (C++/CLI):

__declspec(dllexport) void SimpleTest(int* p)
{
    *p = 1;
}

ここで何が起こっているのかわかりません。.NET 環境がロードされていませんか? Wrapper DLL がロードされていませんか? (モジュールをループしましたが、ラッパーはありませんでした)。

CLR を手動で初期化する必要がありますか?

ローダーロックについて読みましたが、ここでの問題かどうかはわかりません。

4

2 に答える 2

3

ドキュメントからDllMain:

DLL エントリ ポイントで安全に実行できることには、かなりの制限があります。DllMain で呼び出すのが安全でない特定の Windows API については、一般的なベスト プラクティスを参照してください。最も単純な初期化以外が必要な場合は、DLL の初期化関数でそれを行います。DllMain の実行後、DLL 内の他の関数を呼び出す前に、アプリケーションが初期化関数を呼び出すように要求できます。

マネージ コードの呼び出しは、実行できないことの 1 つです。

これに対処する標準的な方法は、DllMain許可されているアクションである にスレッドを作成し、そのスレッドからマネージ コードを呼び出すことです。

于 2015-12-21T21:39:00.667 に答える
0

DLL と共有オブジェクトは、C/C++ 標準では問題のある寿命を持っています。

オペレーティング システムは DLL をロードし、DllMain を呼び出してグローバル変数を初期化し、依存 DLL をロードします。

これは、a) DllMain/global の構築中にローダー ロックが発生している、b) 依存する DLL が読み込まれていない可能性があることを意味します。

これは、CLR がアクティブでない (初期化されていない) 可能性があり、ローダー ロックが必要な場合にハングする可能性があることを意味します。

後まで延期することが最善の解決策です。

class ImportantOnceWork{
    ImportantOnceWork()
     {
         MyEntryPoint();

     }
};

int DoOnce()
{
    static ImportantOnceWork val;
}

次に、DoOnce(); を呼び出します。各フックポイントで。

于 2015-12-21T21:51:20.973 に答える