cclrclr-hosting

Is it possible to host the CLR in a C program?


Every example I can find is in C++, but I'm trying to keep my project in C. Is it even possible to host the CLR in a C program?

If so, can you point me to an example?


Solution

  • As the above comments hint, there is a set of COM APIs for hosting the CLR, and you should be able to call these COM APIs from both C and C++.

    As an example, below is a quick piece of (untested) C code that shows how to start up the CLR and execute a static method of a class in a managed assembly (which takes in a string as an argument and returns an integer). The key difference between this code and its C++ counterpart is the definition of COBJMACROS and the use of the <type>_<method> macros (e.g. ICLRRuntimeHost_Start) to call into the CLR-hosting COM interface. (Note that COBJMACROS must be defined prior to #include'ing mscoree.h to make sure these utility macros get defined.)

    #include <windows.h>
    
    #define COBJMACROS
    #include <mscoree.h>
    
    int main(int argc, char **argv)
    {
        HRESULT status;
        ICLRRuntimeHost *Host;
        BOOL Started;
        DWORD Result;
    
        Host = NULL;
        Started = FALSE;
    
        status = CorBindToRuntimeEx(
                     NULL,
                     NULL,
                     0,
                     &CLSID_CLRRuntimeHost,
                     &IID_ICLRRuntimeHost,
                     (PVOID *)&Host
                     );
        if (FAILED(status)) {
            goto cleanup;
        }
    
        status = ICLRRuntimeHost_Start(Host);
        if (FAILED(status)) {
            goto cleanup;
        }
    
        Started = TRUE;
    
        status = ICLRRuntimeHost_ExecuteInDefaultAppDomain(
                     Host,
                     L"c:\\path\\to\\assembly.dll",
                     L"MyNamespace.MyClass",
                     L"MyMethod",
                     L"some string argument to MyMethod",
                     &Result
                     );
        if (FAILED(status)) {
            goto cleanup;
        }
    
        // inspect Result
        // ...
    
    cleanup:
        if (Started) {
            ICLRRuntimeHost_Stop(Host);
        }
    
        if (Host != NULL) {
            ICLRRuntimeHost_Release(Host);
        }
    
        return SUCCEEDED(status) ? 0 : 1;
    }
    

    This sample should work with .NET 2.0+, although it looks like .NET 4.0 (not yet released) has deprecated some of these APIs in favor of a new set of APIs for hosting the CLR. (And if you need this to work with .NET 1.x, you need to use ICorRuntimeHost instead of ICLRRuntimeHost.)