2

So I'm trying to load up the .NET 4 runtime and run my own C# DLL. The Start() method is throwing a HRESULT=0x1 error. If I comment out the start code, the C# DLL loads and executes, then the Stop() method throws a HRESULT=0x8000ffff error. I've looked for hours and all the code looks like what I have below (I left out all my debugging/error handling). Thank you very much for any tips in advance! =)

    void DotNetLoad()
    {
        ICLRRuntimeHost *pClrHost = NULL;
        ICLRMetaHost *lpMetaHost = NULL;
        MessageBox(0, L"Creating CLR instance.", L"Bootstrap Message", 0);
        HRESULT hr = CLRCreateInstance(
            CLSID_CLRMetaHost,
            IID_PPV_ARGS(&lpMetaHost));
        ICLRRuntimeInfo *lpRuntimeInfo = NULL;
        hr = lpMetaHost->GetRuntime(L"v4.0.30319",
            IID_PPV_ARGS(&lpRuntimeInfo));
        hr = lpRuntimeInfo->GetInterface(
            CLSID_CLRRuntimeHost,
            IID_ICLRRuntimeHost,
            (LPVOID *)&pClrHost);
        hr = pClrHost->Start();
        DWORD dwRet = 0;
        hr = pClrHost->ExecuteInDefaultAppDomain(
            pwzTargetDll,
            pwzNamespaceClass, pwzFunction, L"pwzArgument", &dwRet);
        hr = pClrHost->Stop();
        hr = pClrHost->Release();

    }

I understand the bit about decoupling the init, .NET call, and deinit, but what do you mean by app startup and shutdown? Right now I have DotNetLoad being called from a DLL method that is injected into a remote process. Basically:

extern "C" __Declspec(dllexport) void Initialize()
{
    DotNetLoad(params); //ex.
}
Jeff Atwood
  • 63,320
  • 48
  • 150
  • 153
  • Thanks for the reply! Sorry I don't know much about COM (or what it is exactly). Should I do something like "CoInitializeEx" before starting the CLR code? – Harry Stone Jul 07 '11 at 06:24
  • CoInitialize() for STA (single threaded/message pump dispatched COM calls), or CoInitializeEx() with appropriate flags for MTA (multithreaded COM call dispatching). If you are using MFC with COM/OLE features, you have to call AfxOleInit() (which is a call to CoInitialize() + some other MFC specific initialization). – Jörgen Sigvardsson Jul 07 '11 at 08:40
  • I'd go with an MTA if there is no MFC involved. – Jörgen Sigvardsson Jul 07 '11 at 08:42

1 Answers1

1

By combining runtime init with the assembly method call, followed by runtime deinit, you are executing this code on every call to DotNetLoad().

See the important block here. This leads me to believe that once you load the runtime into your process you don't want to do it again.

Split your initialization / deinitialization out of the method used to call the .NET assembly. Do the initialization only once (at app startup and prior to making the call), and do the deinitialization only once (at app shutdown). I tested this and it worked without error.

Jenia
  • 374
  • 1
  • 4
  • 15
ScottTx
  • 1,483
  • 8
  • 12