无法使用/ CLR选项从Visual c++项目加载CLR

本文关键字:CLR Visual c++ 项目 加载 选项 | 更新日期: 2023-09-27 18:06:44

我试图创建一个Visual c++ Win32控制台应用程序与以下配置:操作系统:Windows 7visual Studio: VS 2012公共语言运行库支持:公共语言运行库支持(/clr[项目属性].

我还创建了一个Visual c# WPF应用程序,并使用该dll从下面提到的c++程序中使用它。

我遵循这个链接的所有说明:https://code.msdn.microsoft.com/CppHostCLR-e6581ee0

问题是我无法启动CLR,即ICLRRunTimeHost:启动方法返回0x1而不是0x0。请帮助/指导我解决我的错误,如果我的代码在概念上是错误的,请指导我。

请查看我的代码粘贴在下面:

#include "stdafx.h"
#include <metahost.h>
#include <mscoree.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; 
        }
    }
//Load an assembly and call the required function
    if (hr == S_OK) // if CLR is started successfully
    {
        DWORD dwRet;
        hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(L"WpfWithoutService.dll", L"WpfWithoutService.MainWindow", L"InitializeComponent", NULL, &dwRet); 
        if (FAILED(hr)) 
        { 
            wprintf(L"CLR 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"); 
            pClrRuntimeHost->Stop()
            pClrRuntimeHost->Release(); 
            pClrRuntimeHost = NULL; 
    } 

    return 0;
}

无法使用/ CLR选项从Visual c++项目加载CLR

ICLRRunTimeHost:Start方法返回0x1而不是0x0

这是S_FALSE,当CLR已经运行时返回。你不能启动两次。

使用以下配置…公共语言运行时支持

这是不合适的,它强制在代码开始运行之前加载并初始化 CLR。您只能在本机c++程序中编写这样的CLR托管代码,该程序而不是使用/CLR构建的

或者换句话说,您根本不需要编写此代码。并且没有明显的理由说明为什么要从代码片段中删除。从Assembly::Load()开始,您可以使用反射来实现完全相同的目的。或者更简单,通过添加对该程序集的引用。真正的意图是很难逆向工程的。如果确实存在,那么只需将/clr选项设置回"No"。