机制介绍
有些时候主程序是通过C/C++实现的,但是我们希望通过托管代码来扩展非托管程序,从而也获得托管代码带来的一系列优点。比如开发效率高,自动垃圾回收等。
运行托管与非托管代码根本区别在于托管代码是进程首先加载CLR然后通过CLR运行托管程序,而非托管代码则是操作系统直接根据其PE Header加载程序分配内存从而运行。因此如果需要通过托管代码来扩展非托管程序,首先要加载CLR来使非托管程序获得运行托管代码的能力。
可以使用以下过程将 CLR 加载到进程中:
- 调用 CLRCreateInstance 函数以获取 ICLRMetaHost 或 ICLRMetaHostPolicy 接口。 CLRCreateInstance 函数取代 .NET Framework 1.1 和 2.0 承载全局静态函数部分中列出的所有 CorBindTo* 函数。
- 调用 ICLRMetaHost::EnumerateInstalledRuntimes、ICLRMetaHost::GetRuntime 或 ICLRMetaHostPolicy::GetRequestedRuntime 方法以获取有效的 ICLRRuntimeInfo 指针。
- 调用 ICLRRuntimeInfo::GetInterface 方法。 为 rclsid 参数指定 CLSID_CLRRuntimeHost,并为 riid 参数指定 IID_ICLRRuntimeHost。
所有这些接口的原型均位于 Metahost.h 文件中,该文件位于 Windows 软件开发工具包 (SDK) 的 Include 目录中。 宿主可以使用 ICLRRuntimeInfo 和 ICLRRuntimeHost 接口来控制要加载哪个版本的运行时以及基本功能(如垃圾回收和程序集加载)的行为。使用 ICLRRuntimeHost 接口可以执行以下操作:
- 通过调用 ICLRRuntimeHost::Start 方法来启动运行时。
- 执行托管代码。
- 获取指向 ICLRControl 接口(可提供对由公共语言运行时实现的管理器的访问)的指针,以及注册实现 IHostControl 接口的宿主控件对象。 公共语言运行时调用 IHostControl 接口来确定宿主实现的管理器。
参考这里 http://msdn.microsoft.com/en-us/library/01918c6x.aspx
实例代码
以下是C++加载CLR运行托管程序的实例代码,启动CLR之后通过调用ExecuteInDefaultAppDomain来运行托管程序SampleManagedApp.exe中名为Test的程序。这里要注意的是ExecuteInDefaultAppDomain只能执行托管代码签名为static int pwzMethodName (String pwzArgument)的方法。
#include <SDKDDKVer.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <metahost.h>
#include <mscoree.h>
#pragma comment(lib, "mscoree.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = nullptr;
ICLRMetaHostPolicy *pMetaHostPolicy = nullptr;
ICLRRuntimeHost *pRuntimeHost = nullptr;
ICLRRuntimeInfo *pRuntimeInfo = nullptr;
HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
if(FAILED(hr))
{
goto cleanup;
}
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pRuntimeHost));
hr = pRuntimeHost->Start();
DWORD dwRet = 0;
hr = pRuntimeHost->ExecuteInDefaultAppDomain(L"SampleManagedApp.exe",
L"SampleManagedApp.Program",
L"Test",
L"Hello World!",
&dwRet);
hr = pRuntimeHost->Stop();
cleanup:
if(pRuntimeInfo != nullptr)
{
pRuntimeInfo->Release();
pRuntimeInfo = nullptr;
}
if(pRuntimeHost != nullptr)
{
pRuntimeHost->Release();
pRuntimeHost = nullptr;
}
if(pMetaHost != nullptr)
{
pMetaHost->Release();
pMetaHost = nullptr;
}
}
相应的托管代码如下,
using System;
namespace SampleManagedApp
{
class Program
{
static void Main(string[] args)
{
}
public static int Test(string s)
{
Console.WriteLine(s);
return 0;
}
}
}
最终将SampleManagedApp.exe与非托管程序放在同一个路径下运行非托管程序,就会得到最终Console中输出:Hello World!
分享到:
相关推荐
MFC程序设计详细实例 第30章 C++CLI CLR编程MFC程序设计详细实例 第30章 C++CLI CLR编程MFC程序设计详细实例 第30章 C++CLI CLR编程MFC程序设计详细实例 第30章 C++CLI CLR编程MFC程序设计详细实例 第30章 C++CLI ...
c++ 通过 clr 方式 封装 原生 c++ dll , 由c# 对其调用 通过创建c++ clr项目dll_test_net,其内部封装纯c++ dll (dll_test_cpp),然后c#项目 test_net调用dll_test_net。 所有项目由vs2008创建。 防入坑提示: clr...
C++&CLR(VS2015)编写 Windows 窗体应用程序
第1章Visual C++ 2010 CLR字符串与正则表达式 第2章Visual C++ 2010 CLR集合 第3章Visual C++ 2010 CLR数据访问 第4章Visual C++ 2010 CLR 文件和注册表操作 第5章Visual C++ 2010 CLR使用GDI+绘图 第6章Visual C++ ...
Visual Studio 从2012版本开始,取消了C++语言下CLR Windows窗体应用程序的模板,手动配置起来步骤较为繁琐。本补丁能够在Visual Studio 2012及2013中恢复这一模板,方便程序员开发相应的应用程序。
C++ CLI\CLR 编程入门 中文,入门级文档,可快速从C++ C#程序员转型
源程序 Visual C++2010 CLR开发电子书源程序
Viual C++ CLR开发电子书+源程序
C#使用CLR调用C++的DLL库的windows完整解决方案 说明如下: 1、工程一:C++的DLL 2、工程二:C++的CLR的类库 3、工程三:C#的exe
Visual_C++2010_CLR开发电子书07
VS2015 C++&CLR 编写 Windows 窗体应用程序
Visual Studio 2012中新建C++/CLR项目时,没有了Windows Forms(windows窗体应用程序)模板。此补丁恢复了VS2012对C++/CLR中Windows Forms的支持。 使用方法:解压后,将文件夹下的文件复制到VS2012安装路径下。...
Visual C++2010 CLR开发电子书 Visual C++2010 权威指南光盘附带
visual c++ 2010 CLR 开发电子书
采用CLR技术对c++封装,相当于可以使c#直接使用c++的类
VS2012中,取消了在C++/CLR下的WINDOWS窗体应用程序模板。这个补丁就是恢复这项模板,而且增加了更多的控件。
winform 加载CLR源码! 很值得下载看看!资源免费,大家分享!!
VS2012新建项目中的C++-CLR部分是没有Windows窗体选项的。 下载后解压到VS的安装目录,如有提示合并文件夹或者替换文件,请选择允许合并及替换。
因项目需要,要用C#程序调用C++的一个DLL库,了解到有个工具叫CLRInsideOut,其中一个的功能就是把C++下的结构体或者函数声明转换成C#下的定义,自动生成 C# 代码。 现上传上来,方便大家编码,给有需要的人,个人...