无法使用 /clr 选项从 Visual C++ 项目加载 CLR
Unable load CLR from Visual C++ project with /clr option
我正在尝试创建具有以下配置的 Visual C++ Win32 控制台应用程序:
OS : Windows 7
视觉工作室:VS 2012
公共语言运行时支持:公共语言运行时支持(/clr[项目属性]。
我还创建了一个 Visual C# WPF 应用程序并使用该 dll 从下面提到的 c++ 程序中使用它。
我遵循此 link 中的所有说明:https://code.msdn.microsoft.com/CppHostCLR-e6581ee0
问题是我无法启动 CLR,即 ICLRRunTimeHost:Start 方法 returns 0x1 而不是 0x0.Please help/guide 我来解决我的错误,如果我的代码是概念上有误,请指导我。
请在下面找到我粘贴的代码:
#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
即S_FALSE,当CLR已经运行时返回。不能启动两次。
with following configuration ... Common Language Runtime Support
这不合适,它强制 CLR 在此代码开始 运行 之前加载和初始化。您只能在 而不是 使用 /clr 构建的本机 C++ 程序中编写这样的 CLR 托管代码。
或者说,你根本不需要写这段代码。并且没有明显的理由说明您想要从代码段中获取。您可以通过使用反射来实现完全相同的效果,从 Assembly::Load() 开始。或者更简单,通过添加对该程序集的引用。实际意图很难逆向工程。如果确实有一个,那么只需将 /clr 选项设置回 "No".
我正在尝试创建具有以下配置的 Visual C++ Win32 控制台应用程序: OS : Windows 7 视觉工作室:VS 2012 公共语言运行时支持:公共语言运行时支持(/clr[项目属性]。
我还创建了一个 Visual C# WPF 应用程序并使用该 dll 从下面提到的 c++ 程序中使用它。
我遵循此 link 中的所有说明:https://code.msdn.microsoft.com/CppHostCLR-e6581ee0
问题是我无法启动 CLR,即 ICLRRunTimeHost:Start 方法 returns 0x1 而不是 0x0.Please help/guide 我来解决我的错误,如果我的代码是概念上有误,请指导我。
请在下面找到我粘贴的代码:
#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
即S_FALSE,当CLR已经运行时返回。不能启动两次。
with following configuration ... Common Language Runtime Support
这不合适,它强制 CLR 在此代码开始 运行 之前加载和初始化。您只能在 而不是 使用 /clr 构建的本机 C++ 程序中编写这样的 CLR 托管代码。
或者说,你根本不需要写这段代码。并且没有明显的理由说明您想要从代码段中获取。您可以通过使用反射来实现完全相同的效果,从 Assembly::Load() 开始。或者更简单,通过添加对该程序集的引用。实际意图很难逆向工程。如果确实有一个,那么只需将 /clr 选项设置回 "No".