承载(Host)通用语言执行时

承载(Host)通用语言执行时(CLR)

还有一种使用COM 的方法是是把须要集成的 F# 代码与已有的 C/C++ 应用程序集成到一起。开成自己定义的承载通用语言执行时。通用语言执行时就是 C++ 应用程序,且有一些可用的库(.lib)文件。能够在标准的 C++ 应用程序中链接它。

承载通用语言执行时的代码要比载入 COM 库的代码稍许复杂一点,但不须要复杂的注冊 COM 库了;这种方法还可能以很细粒度地控制通用语言执行时的行为。尽管。我们会发现默认的行为对于大多数情况已经很好了;可是,这样的方法并不适合高性能的在 C++ 和 F# 之间调用,由于,我们差点儿不能控制使用的签名(signatures
used)[ 不知所云],通用语言执行时的方法调用是通过反射(reflection)完毕的,这样,找到模块和方法是通过字符串的比較,因此,可能很慢。

然而。假设我们要调用 F# 代码中很重要的部分,就会发现调用的成本很快冰被摊销了。

我们来看一下代码,它使用自己定义的通用语言执行时承载,来调用一个 F# 的方法,代码是 Visual Studio C++ 项目。我们须要注意代码中的这些地方:

#include <mscoree.h> 告诉 C++ 编译器导入头文件,它包括了载入通用语言执行时的函数和接口。

然后,须要载入并初始化这个通用语言执行时。这是通过在结果对象上调用CorBindToRuntimeEx 加 Start 方法实现的。

通过调用ExecuteInDefaultAppDomain 方法在通用语言执行时程序集中执行方法。

以下是完整的 C++ 程序清单:

// !!! C++ Source !!!

#include "stdafx.h"

// the head file that exposes theC++ methods and interfaces

#include <mscoree.h>

// the applications main entry point

int _tmain(int argc, _TCHAR* argv[])

{

// pointer to the CLR host object

ICLRRuntimeHost*pClrHost = NULL;

// invoke the method that loads the CLR

HRESULT hrCorBind= CorBindToRuntimeEx(

NULL, // CLR version - NULL load the latest available

L"wks", // GCType ("wks" = workstation or "svr" = Server)

0,

CLSID_CLRRuntimeHost,

IID_ICLRRuntimeHost,

(PVOID*)&pClrHost);

// Start the CLR.

HRESULT hrStart =pClrHost->Start();

// Define the assembly, type, function to load,

// as well as the parameter and variable for the returnvalue

LPCWSTRpwzAssemblyPath = L"fslib.dll";

LPCWSTRpwzTypeName = L"Strangelights.TestModule";

LPCWSTRpwzMethodName = L"print";

LPCWSTRpwzMethodArgs = L"Hello world!";

DWORD retVal;

// Load an assembly and execute a method in it.

HRESULT hrExecute= pClrHost->ExecuteInDefaultAppDomain(

pwzAssemblyPath, pwzTypeName,

pwzMethodName,pwzMethodArgs,

&retVal);

// print the result

printf("retVal: %i", retVal);

}

除了这段代码以外。还须要链接mscoree.lib。这在Windows Platform SDK 中。我们须要知道的,也是唯一特殊的地方,是在 F# 这边的函数的签名必须是string -> int。这里的与 C++ 程序一起执行的 F# 函数很easy:

module Strangelights.TestModule

// function will be invoked

let print s =

printfn "%s" s

0

演示样例的执行结果例如以下:

Hello world!

retVal: 0

注意

很多其它有关自己定义通用语言承载的信息。參见 MSDN 上Alessandro Catorcini 和 Piotr Puszkiewicz 的文章:http://msdn.microsoft.com/en-us/magazine/cc163567.aspx

第十四章小结

在这一章。我们讨论了一些 F# 中用于兼容性和互操作的高级技术。尽管这些技术有些是绝对难以掌握。但它也会给 F# 编程增添了巨大的灵活性。

[

host,微软翻译成承载,网络上多数翻译成寄宿,托管。前面两个被动的成份很多其它一些,最后的主动成份很多其它一些,因此。译成托管更好。

]

[ 全文完 ]

时间: 2024-10-11 04:35:09

承载(Host)通用语言执行时的相关文章

承载(Host)通用语言运行时

承载(Host)通用语言运行时(CLR) 另一种使用COM 的方法是是把需要集成的 F# 代码与已有的 C/C++ 应用程序集成到一起,开成自定义的承载通用语言运行时,通用语言运行时就是 C++ 应用程序,且有一些可用的库(.lib)文件,可以在标准的 C++ 应用程序中链接它.承载通用语言运行时的代码要比加载 COM 库的代码稍许复杂一点,但不需要复杂的注册 COM 库了:这个方法还可能以非常细粒度地控制通用语言运行时的行为,虽然,我们会发现默认的行为对于大多数情况已经非常好了:但是,这种方法

类型与通用语言运行时:类型转换

CLR 最重要的一个特性就是类型安全.CLR 在运行时总能知道一个对象的类型.我们也可以用过调用 GetType方法来得到对象的准确类型.因为该方法是一个虚方法.所以我们不可能利用它来篡改一个类型的信息. 例如:我们不可能重写 Employee 类的 GetType方法使之返回一个SpaceShuttle类型. 作为开发人员,我们经常会遇到需要将一个对象转换为其他类型. CLR 允许我们将对象转换为其原来的类型或者它的任何一个基类型.各个编程语言自己决定如何提供这些转型操作. 例如,C# 不需要

类型与通用语言运行时:System.Object

CLR 要求每个类型最终都要继承自 System.Object 类型 1 //隐式继承 Object 2 class Employee { 3 ... 4 } 5 6 //显示继承继承 Object 7 class Employee : System.Object { 8 ... 9 } 类型定义(C#)描述 System.object 的公有方法 Equals:如果两个对象具有相同的值,方法返回 true GetHashCode:方法返回对象的值的散列码.如果一个对象被用作散列表的一个键值,那

Android执行时ART载入OAT文件的过程分析

在前面一文中,我们介绍了Android执行时ART,它的核心是OAT文件.OAT文件是一种Android私有ELF文件格式,它不仅包括有从DEX文件翻译而来的本地机器指令.还包括有原来的DEX文件内容.这使得我们无需又一次编译原有的APK就能够让它正常地在ART里面执行.也就是我们不须要改变原来的APK编程接口. 本文我们通过OAT文件的载入过程分析OAT文件的结构,为后面分析ART的工作原理打基础. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! <An

iOS 执行时

一.什么是执行时(Runtime)? 执行时是苹果提供的纯C语言的开发库(执行时是开发中经经常使用到的底层技术) 二.执行时的作用? 能获得某个类的全部成员变量 能获得某个类的全部属性 能获得某个类的全部方法 交换方法实现 能动态加入一个成员变量 能动态加入一个属性 能动态加入一个方法 三.案例:执行时获取成员变量名称 1.分析 #import <Foundation/Foundation.h> #import "CKPerson.h" #import <objc/r

C#获取程序代码执行时长

ArrayList list = new ArrayList(); long startTicks = DateTime.Now.Ticks; for (int i = 0; i < 1000000; i++) { list.Add(i); } for (int i = 0; i < 1000000; i++) { int value = (int)list[i]; } long endTicks = DateTime.Now.Ticks; Console.WriteLine("ar

java线程 - 线程唤醒后并被执行时,是在上次阻塞的代码行重新往下执行,而不是从头开始执行

今天重新把昨晚的线程同步面试题做一遍时,发现实际情况运行下来时,线程一直不同步.后来经过不断测试,发现自己的一个误区. 之前一直以为,线程如果被唤醒后再次执行时,会从头开始运行这个线程,也就是重新运行Runnable中的run()方法: 而实际情况是,被唤醒并且被执行的线程是从上次阻塞的位置从下开始运行,也就是从wait()方法后开始执行. 所以判断是否进入某一线程的条件 是用while判断,而不是用If判断判断. 下面举例说明: 如果三个线程同步工作,第一个线程打印1,2,3,4,5   ,然

shell脚本在执行时,向脚本传递参数

Shell脚本在执行时,也可以像命令和应用程序一样,接收脚本参数. 一个应用实例: vi addhead.sh: suaddhead ns=591 <$1 |sushw key=dt a=20000|sushw key=fldr,cdp a=1,1 b=0,1 c=1,0 j=1301,1301> $2 执行: ./addhead.sh rtm_step10_lap.dat rtm_step10_lap.su(其中,rtm_step10_lap.dat是输入数据,输入给$1, 输出为:rtm_

【java】计算一段代码执行时长

1 public class Test_currentTimeMillis { 2 public static void main(String[] args) { 3 long start=System.currentTimeMillis(); 4 for(int i=0;i<Integer.MAX_VALUE;i++){} 5 long end=System.currentTimeMillis(); 6 System.out.println("for语句执行时长:"+(end