2

私は、rundll32 で読み込むことができ、マネージ コードを実行する前に .Net ランタイム ライブラリの存在をチェックする混合マネージ/アンマネージ DLL を作成したいと考えています。

using namespace System;

void SomeManagedCode()
{
    Diagnostics::Debug::WriteLine("Hello managed code!");
}

#pragma managed(push,off)

bool isRuntimeInstalled()
{
    // check for runtime using some *unmanaged* code

    return true;
}

extern "C" __declspec(dllexport) void _stdcall RunDllEntryPoint(
            HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow)
{
    if (isRuntimeInstalled())
    {
        SomeManagedCode();
    }
    else
    {
        OutputDebugString(L".net framework not installed");
    }
}

#pragma managed(pop)

これを実現するために/DELAYLOAD、CLR (mscoree.dll など) を試して、SomeManagedCode() が呼び出されたときにのみ読み込まれるようにしました。ただし、CLR は RunDllEntryPoint() が呼び出される前でも読み込まれます (読み込まれたモジュールのリストに mscoree.dll が表示されます)。これは、コンパイラが _CorDllMain() を呼び出すコードにリンクしているためだと思います。これは、自分のエントリポイントが呼び出される前にランタイムを強制的にロードする必要があります。

これを再パッケージ化して機能させる方法があることは知っています。たとえば、マネージ コードを別の DLL に分割しますが、上記のコードを単一の DLL で機能させる方法があるかどうかに興味があります。

CLR dll を本当に遅延ロードすることは可能ですか?

4

1 に答える 1

0

それをトリガーしている RunDllEntryPoint の関数呼び出し「SomeManagedCode()」の存在でしょうか? 間接的なレイヤーを追加することで問題を解決できますか?

#pragma managed
void SomeManagedCode()
{
    Diagnostics::Debug::WriteLine("Hello managed code!");
}
#pragma unmanaged
void CallSomeManagedCode()
{
    SomeManagedCode();
}
extern "C" __declspec(dllexport) void _stdcall RunDllEntryPoint(
        HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow)
{
    if (isRuntimeInstalled())
    {
        CallSomeManagedCode();
    }
    else
    {
        OutputDebugString(L".net framework not installed");
    }
}

私は同様の状況にあり、.NET が間違ったスレッドからロードされるのを防ごうとしました。間接レイヤーを追加することで、つまりネイティブ エントリ ポイントからマネージ コードやマネージ クラスを直接呼び出さないようにすることで、.NET をプッシュすることができました。 NET のロードは後で (私の場合は、別のスレッドから実行できるようになるまで)。

于 2015-06-03T16:18:49.727 に答える