Click here to Skip to main content
15,886,578 members
Articles / Programming Languages / C#

Calling a C# Method from C/C++ (Native Process)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
8 Sep 2014CPOL2 min read 16.2K   16   1
Calling a C# method from C/C++ (native process)

I received a challenge from a friend (lost a bet...) regarding how to load a managed (C#) DLL in a native (C++) process by using the Common Language Runtime (CLR). This is confirmed to work with .NET Framework 4.0.

The trick is to host the CLR in the process and using it to load the managed DLL.

// This tutorial contains C/C++; you have been warned.

1) Making a C# DLL

This is the only part where we'll be using C# - so enjoy it as much as you can! We'll make a dummy DLL that will be later loaded into a native application.

I came up with this sophisticated code (feel free to improvise), but the function that you want to call must return something (preferably int).

C#
using System.Windows.Forms;

namespace dllNamespace
{
    public class dllClass
    {
        public static int ShowMsg(string msg)
        {
            MessageBox.Show(msg);
            return 0;
        }
    }
}

2) Hosting the CLR in a Native Process

First things first, you'll need to include these 2 lines:

C++
#include <metahost.h>

#pragma comment(lib, "mscoree.lib")

We have to call CLRCreateInstance() in order to gain access to ICLRMetaHost. This interface contains various methods that will provide general information about .NET Framework.

From there, it is required to focus on one version of the framework (in this tutorial, I'm working with v4.0.30319) - calling ICLRMetaHost::GetRuntime() will return a pointer to another interface (ICLRRuntimeInfo), which contains...more methods. (this is the upgraded version of ICorRuntimeHost).

The next step is calling ICLRRuntimeInfo::GetInterface which loads the CLR into the current process and allows us to use some runtime pointers.

Finally, start the runtime host (if it's not running already) using ICLRRuntimeHost::Start().

3) Calling a Method from the Managed DLL

This is done via the runtime host that we struggled to load earlier. Using ICLRRuntimeHost::ExecuteInDefaultAppDomain() with a bunch of arguments does the job pretty well.

The method looks like this:

C++
HRESULT ExecuteInDefaultAppDomain (

    [in] LPCWSTR pwzAssemblyPath,  // absoulte path to the managed dll (not relative!)

    [in] LPCWSTR pwzTypeName,      // name of the class for example: dllNamespace.dllClass

    [in] LPCWSTR pwzMethodName,    // name of the method 

    [in] LPCWSTR pwzArgument,      // argument(s)

    [out] DWORD *pReturnValue      // this is what the method returns

);

Source Code

This is the whole source code:

C++
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")

int main()
{
    ICLRMetaHost* metaHost = NULL;
    ICLRRuntimeInfo* runtimeInfo = NULL;
    ICLRRuntimeHost* runtimeHost = NULL;

    if (CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&metaHost) == S_OK)
        if (metaHost->GetRuntime(L"v4.0.30319", 
        IID_ICLRRuntimeInfo, (LPVOID*)&runtimeInfo) == S_OK)
            if (runtimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, 
               (LPVOID*)&runtimeHost) == S_OK)
                if (runtimeHost->Start() == S_OK)
	        {		
		    DWORD pReturnValue;
		    runtimeHost->ExecuteInDefaultAppDomain(L"C:\\random.dll", 
            L"dllNamespace.dllClass", L"ShowMsg", L"It works!!", &pReturnValue);
	
		    runtimeInfo->Release();
		    metaHost->Release();
		    runtimeHost->Release();
                }
    return 0;
}

Short advice: Always check that each HRESULT returned is equivalent to S_OK.

P.S.: Due to some problems with my compiler, I couldn't test this code properly - last time, it worked pretty well... hope it still does so.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student
Romania Romania
Master's student @ ACS / UPB (Advanced Cybersecurity), Graduate Teaching Assistant, Junior Security Researcher. Also, webmaster of coding.vision

Comments and Discussions

 
GeneralVery cool Pin
codefabricator11-Sep-14 5:37
codefabricator11-Sep-14 5:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.