我目前正在尝试从非托管C++应用程序从C#DLL调用函数。

经过数小时的网络搜索和搜索,我发现我有一些选择。

我可以使用COM,DllExport或对委托(delegate)使用反向PInvoke。最后一个听起来对我来说最有吸引力,因此在搜索了SO之后,我得到了here

它指出该文章显示了如何使用反向PInvoke,但是看起来C#代码必须先导入C++ Dll,然后才能使用它。

我需要能够使用C++来调用C#Dll函数,而无需先运行C#应用程序。

也许反向PInvoke不是做到这一点的方法,但是当涉及到低级内容时,我还是没有经验,因此任何有关此操作的指示或技巧都将是不错的。

链接中的代码是

C#

using System.Runtime.InteropServices;

public class foo
{
    public delegate void callback(string str);

    public static void callee(string str)
    {
        System.Console.WriteLine("Managed: " +str);
    }

    public static int Main()
    {
        caller("Hello World!", 10, new callback(foo.callee));
        return 0;
    }

    [DllImport("nat.dll",CallingConvention=CallingConvention.StdCall)]
    public static extern void caller(string str, int count, callback call);
}

C++
#include <stdio.h>
#include <string.h>

typedef void (__stdcall *callback)(wchar_t * str);
extern "C" __declspec(dllexport) void __stdcall caller(wchar_t * input, int count, callback call)
{
    for(int i = 0; i < count; i++)
    {
        call(input);
    }
}

最佳答案

恩,只需启动您自己的CLR主机并运行所需的操作即可:

#include <mscoree.h>
#include <stdio.h>
#pragma comment(lib, "mscoree.lib")

void Bootstrap()
{
    ICLRRuntimeHost *pHost = NULL;
    HRESULT hr = CorBindToRuntimeEx(L"v4.0.30319", L"wks", 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*)&pHost);
    pHost->Start();
    printf("HRESULT:%x\n", hr);

    // target method MUST be static int method(string arg)
    DWORD dwRet = 0;
    hr = pHost->ExecuteInDefaultAppDomain(L"c:\\temp\\test.dll", L"Test.Hello", L"SayHello", L"Person!", &dwRet);
    printf("HRESULT:%x\n", hr);

    hr = pHost->Stop();
    printf("HRESULT:%x\n", hr);

    pHost->Release();
}

int main()
{
    Bootstrap();
}

10-06 00:06