简体   繁体   English

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

[英]Unable load CLR from Visual C++ project with /clr option

I am trying to create a Visual C++ Win32 Console application with following configuration: OS : Windows 7 Visuals Studio : VS 2012 Common Language Runtime Support : Common Language Runtime Support(/clr[Project Properties]. 我正在尝试创建具有以下配置的Visual C ++ Win32控制台应用程序:操作系统:Windows 7 Visuals Studio:VS 2012公共语言运行时支持:公共语言运行时支持(/ clr [项目属性]。

Also i have created a Visual C# WPF application and use that dll to use it from the below mentioned c++ program. 我也创建了一个Visual C#WPF应用程序,并使用该dll从下面提到的c ++程序中使用它。

I follow all the instructions from this link: https://code.msdn.microsoft.com/CppHostCLR-e6581ee0 我按照此链接中的所有说明进行操作: https : //code.msdn.microsoft.com/CppHostCLR-e6581ee0

Problem is i am not able to start the CLR ie ICLRRunTimeHost:Start method returns 0x1 instead of 0x0.Please help/guide me to solve my error and if my code is conceptually wrong please guide me for the same. 问题是我无法启动CLR,即ICLRRunTimeHost:Start方法返回0x1而不是0x0。请帮助/指导我解决我的错误,如果我的代码概念上错误,请同样指导我。

Please find my code pasted below : 请在下面找到我的代码:

#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;
}

ICLRRunTimeHost:Start method returns 0x1 instead of 0x0 ICLRRunTimeHost:Start方法返回0x1而不是0x0

That is S_FALSE, returned when the CLR is already running. 即S_FALSE,在CLR已经运行时返回。 You can't start it twice. 您不能启动两次。

with following configuration ... Common Language Runtime Support 具有以下配置...公共语言运行时支持

That is not appropriate, it forces the CLR to get loaded and initialized before this code starts running. 这是不合适的,它迫使CLR 此代码开始运行之前被加载和初始化。 You only write CLR hosting code like this in a native C++ program that is not built with /clr. 您只能在使用/ clr构建的本地C ++程序中编写此类CLR托管代码。

Or in other words, you don't need to write this code at all. 换句话说,您根本不需要编写此代码。 And there's no visible reason why you'd want to from the snippet. 并没有明显的理由为什么要摘录。 You can achieve the exact same thing by using Reflection, starting with Assembly::Load(). 从Assembly :: Load()开始,您可以通过使用Reflection实现完全相同的功能。 Or simpler yet, by adding a reference to that assembly. 或更简单的是,通过添加对该程序集的引用。 Actual intention is hard to reverse-engineer. 实际意图很难逆向工程。 If there actually is one then just set the /clr option back to "No". 如果实际上有一个,则只需将/ clr选项设置回“ No”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM