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

1

6

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?

Putrid answered 29/8, 2009 at 2:6 Comment(4)
CLR API is a COM API. Basically, you should be calling COM interfaces in C.Oxpecker
... and for doing so, you can find an article here: codeproject.com/KB/COM/com_in_c1.aspxOxpecker
I'm going to be honest and say that I have absolutely no idea what I'm doing. I'm a C# guy, not a C guy, so that article makes little sense to me. Is there a specific example of hosting the CLR, creating a .NET object instance, and executing a method on it (which I realize is probably fairly complicated)?Putrid
In particular, you don't need the COM in Plain C article at all, hosting the CLR is much easier. It's nice overview article though.Maidstone
A
10

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.)

Adlib answered 3/9, 2009 at 8:58 Comment(1)
Any guess why this won't work: #21537838 ?Beauvoir

© 2022 - 2024 — McMap. All rights reserved.