c# - 使用 ExecuteInDefaultAppDomain 调用主函数 C# 控制台应用程序

标签 c# c++ clr

尝试从非托管 native c++ 代码加载 CLR,然后使用 ExecuteInDefaultAppDomain 函数调用在 win32 c# 控制台应用程序中定义的函数。
实际上我正在尝试调用静态 void Main(string [] args) 即入口点函数。但是在调用 ExecuteInDefaultAppDomain 时,如下面的代码所示,它返回 0x80131513(COR_E_MISSINGMETHOD)。请帮我解决问题,我的概念是错了,请指导我。

请在下面找到粘贴的 c++ 代码:

#include "stdafx.h"
#include <metahost.h>
#include <mscoree.h>
#include <assert.h> 
//#include <Windows.h>

//#using <WpfWithoutService.dll>
//using namespace System;
//using namespace System::Threading;

//using namespace WpfWithoutService;

#pragma comment(lib, "mscoree.lib")
/*ref class MainWinClass
{
public:
    void MainForm()
    {
        MainWindow^ mainwin = gcnew MainWindow();
        //mainwin->Activate();
        //mainwin->InitializeComponent();
    }
};*/

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr; 
    //BOOL fLoadable;

    ICLRMetaHost *pMetaHost = NULL;
    LPCWSTR pwzVersion = (LPCWSTR)"v4.0.30319";


    //hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost); 
    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
    if (FAILED(hr)) 
    { 
        wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr); 
    }

    ICLRRuntimeInfo *pRuntimeInfo = NULL; 
// Get the ICLRRuntimeInfo corresponding to a particular CLR version.
    //hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID *)&pRuntimeInfo); 
    hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)); 
    if (FAILED(hr)) 
    { 
        wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr); 
        //goto Cleanup; 
    } 


/*Check if the specified runtime can be loaded into the process. This  
// method will take into account other runtimes that may already be  
// loaded into the process and set pbLoadable to TRUE if this runtime can  
// be loaded in an in-process side-by-side fashion.  

    hr = pRuntimeInfo->IsLoadable(&fLoadable); 
    if (FAILED(hr)) 
    { 
        wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr); 
        //goto Cleanup; 
    } 


    if (!fLoadable) 
    { 
        wprintf(L".NET runtime %s cannot be loaded\n", "4.0.30319.18063"); 
        //goto Cleanup; 
    }*/


// Load the CLR into the current process and return a runtime interface  pointer. 
    ICLRRuntimeHost *pClrRuntimeHost = NULL;
    hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost)); 
    if (FAILED(hr)) 
    { 
        wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr); 
    }


// Start the CLR.
    if (hr == S_OK)
    {
        hr = pClrRuntimeHost->Start(); 
        if (FAILED(hr)) 
        { 
            wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr); 
            //goto Cleanup; 
        }
    }


/*Create a instance of the class declared in c# dll

    //MainWindow^ mainwin = gcnew MainWindow();

    //mainwin->SetupLogFiles("iptcom_debug_WpfWithoutService.txt");

    MainWinClass^ win = gcnew MainWinClass;

    ThreadStart^ threadDelegate = gcnew ThreadStart(win, &MainWinClass::MainForm);
    Thread^ newThread = gcnew Thread(threadDelegate, 0);
    newThread->SetApartmentState(ApartmentState::STA);
    newThread->Start();*/

//Load an assembly and call the required function
    if (hr == S_OK) // if CLR is started successfully
    {
        DWORD dwRet;
        hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(L"D:\\IPTCom\\IPTComServiceTest_Canada\\IPTComServiceTests_rev2\\Unmanaged_App\\ConsoleApplication.exe", L"ConsoleApplication.Program", L"Main",L"", &dwRet); 
        if (FAILED(hr)) 
        { 
            wprintf(L"ExecuteInDefaultAppDomain failed to start w/hr 0x%08lx\n", hr); 
        } 
    }


    if (pMetaHost) 
    { 
        pMetaHost->Release(); 
        pMetaHost = NULL; 
    } 
    if (pRuntimeInfo) 
    { 
        pRuntimeInfo->Release(); 
        pRuntimeInfo = NULL; 
    } 
    if (pClrRuntimeHost) 
    { 
        // Please note that after a call to Stop, the CLR cannot be  
        // reinitialized into the same process. This step is usually not  
        // necessary. You can leave the .NET runtime loaded in your process. 
        //wprintf(L"Stop the .NET runtime\n"); 
        //if (pClrRuntimeHost->Stop() == S_OK) 
        if (1) 
        {
            pClrRuntimeHost->Release(); 
            pClrRuntimeHost = NULL; 
        }
        else
        {
            pClrRuntimeHost->Release(); 
            pClrRuntimeHost = NULL; 
        }
    } 


    return 0;
}

最佳答案

ExecuteInDefaultAppDomain 只能调用具有签名的函数:

static int pwzMethodName (String pwzArgument)

由于程序的 Main() 签名不同,调用无法找到您的函数。您可以通过包装从不同函数调用 Main 函数来解决此问题:
static int HostingMain(String args)
{
    Main(new string[] { args });
    return 0;
}

然后将您对 C 代码的调用修改为:
        hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(L"D:\\IPTCom\\IPTComServiceTest_Canada\\IPTComServiceTests_rev2\\Unmanaged_App\\ConsoleApplication.exe", L"ConsoleApplication.Program", L"HostingMain",L"", &dwRet); 

关于c# - 使用 ExecuteInDefaultAppDomain 调用主函数 C# 控制台应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31874806/

相关文章:

c# - BackGroundWorker 不在后台执行

c++ - 使用 'std::cin>>int>>string' 可以在没有空格的情况下工作吗?

c++ - 64 位 dll 的大小比 32 位大 50%

.net - 实现调试器支持: choice of debugging API

jvm - JVM 或 CLR 是否使用寄存器来运行 JIT 代码?

c# - 如何使软件安全?

c# - 将 .net 4.0 中的 Entity Framework 与 Oracle 数据库一起使用 - 可能吗?

c++ - C++ Boost 中的线程数组

visual-studio - 运行时 fatal error - 可能是 CLR 错误

c# - 从 C# 中的 XPathSelectElement(s) 返回值