\t\tDLR 动态语言运行时

DLR(动态语言运行时)为.NET Framework添加了适用于动态语言的服务,简化了动态语言的开发并增强了与静态类型语言的互操作性。通过DLR,动态语言如Python和Ruby能在.NET平台上更高效地运行,同时提供了自上而下的开发方式和快速反馈循环。

动态语言运行时 (DLR) 是一种新运行时环境,它将一组适用于动态语言的服务添加到 CLR。借助于 DLR,可以更轻松地开发要在 .NET Framework 上运行的动态语言,而且向静态类型化语言添加动态功能也会更容易。为了支持 DLR,在 .NET Framework 中添加了新 System.Dynamic 命名空间。

动态语言可以在运行时标识对象的类型,而在类似 C# 和 Visual Basic 的静态类型化语言中(当您使用 Option Explicit On 时),您必须在设计时指定对象类型。动态语言有:Lisp、Smalltalk、JavaScript、PHP、Ruby、Python、ColdFusion、Lua、Cobra 和 Groovy。

大多数动态语言都会向开发人员提供以下优点

可以使用快速反馈循环(REPL 或读取-计算-打印循环)。这样,您就可以在输入几条语句之后立即执行它们以查看结果。

同时支持自上而下的开发和更传统的自下而上的开发。例如,当您使用自上而下的方法时,可以调用尚未实现的函数,然后在需要时添加基础实现。

更易于进行重构和代码修改操作,原因是您不必在代码中四处更改静态类型声明。

利用动态语言可以生成优秀的脚本语言。利用新的命令和功能,客户可以轻松地扩展使用动态语言创建的应用程序。动态语言还经常用于创建网站和测试工具、维护服务器场、开发各种实用工具以及执行数据转换。

DLR 的目的是允许动态语言系统在 .NET Framework 上运行,并为动态语言提供 .NET 互操作性。在 Visual Studio 2010 中,DLR 将动态对象引入到 C# 和 Visual Basic 中,以便这些语言能够支持动态行为,并且可以与动态语言进行互操作。

DLR 还可帮助您创建支持动态操作的库。例如,如果您具有一个使用 XML 或 JavaScript 对象表示法 (JSON) 对象的库,则对于使用 DLR 的语言,您的对象可以显示为动态对象。这使库用户能够编写语法更简单且更自然的代码,以便操作对象和访问对象成员。

例如,在 C# 中,您可能会使用下面的代码来递增 XML 中的计数器值。

Scriptobj.SetProperty("Count", ((int)GetProperty("Count")) + 1);

通过使用 DLR,您可以改用下面的代码来执行相同的操作。

scriptobj.Count += 1;

与 CLR 类似,DLR 是 .NET Framework 的一部分,并随 .NET Framework 和 Visual Studio 安装包一起提供。DLR 的开放源代码版本还可以从 CodePlex 网站下载获得。

说明
DLR 的开放源代码版本具有 Visual Studio 和 .NET Framework 中包含的 DLR 的所有功能。此版本还提供对语言实现的其他支持。有关更多信息,请参见 CodePlex 网站上的相关文档。

使用 DLR 开发的语言的示例包括:

  • IronPython。在 CodePlex 网站上作为开放源代码软件提供。

  • IronRuby。在 RubyForge 网站上作为开放源代码软件提供。

DLR 的主要优点

简化动态语言到 .NET Framework 的移植
借助于 DLR,语言实施者不必再按传统的方式来创建词法分析器、语法分析器、语义分析器、代码生成器以及其他工具。若要使用 DLR,语言需要生成表达式树(以树形结构表示语言级代码)、运行时帮助器例程以及用于实现 IDynamicMetaObjectProvider 接口的可选动态对象。DLR 和 .NET Framework 可以自动执行许多代码分析和代码生成任务。这样,语言实施者就可以将精力集中在独有的语言功能上。

允许在静态类型化语言中使用动态功能
现有的 .NET Framework 语言(如 C# 和 Visual Basic)可以创建动态对象,并将动态对象与静态类型化对象一起使用。例如,C# 和 Visual Basic 可以将动态对象用于 HTML、文档对象模型 (DOM) 和 .NET 反射。

提供 DLR 和 .NET Framework 的未来好处
通过使用 DLR 实现的语言可以从将来的 DLR 和 .NET Framework 改进中获益。例如,如果 .NET Framework 发布的新版本改进了垃圾回收器或加快了程序集加载时间,则通过使用 DLR 实现的语言会立即获得相同的好处。如果 DLR 优化了某些方面(如编译功能得到改进),则通过使用 DLR 实现的所有语言的性能也会随之提高。

允许共享库和对象
使用一种语言实现的对象和库可供其他语言使用。DLR 还允许在静态类型化语言和动态语言之间进行互操作。例如,C# 可以声明一个动态对象,而此对象使用利用动态语言编写的库。同时,动态语言也可以使用 .NET Framework 中的库。

提供快速的动态调度和调用
DLR 通过支持高级多态缓存,能够快速执行动态操作。DLR 首先会创建一些规则以将使用对象的操作绑定到必需的运行时实现,然后缓存这些规则,以避免在对同一类型的对象连续执行相同代码期间,出现将耗尽资源的绑定计算。

动态语言运行时体系结构概述

public enum StringSearchOption //自定义动态对象使用一个枚举来确定搜索条件
{
    StartsWith,
    Contains,
    EndsWith
}

using System.IO;
using System.Dynamic;
class DynamicXMLNode : DynamicObject
{
    XElement node;
public DynamicXMLNode(XElement node)
    {
        this.node = node;
    }
    public DynamicXMLNode()
    {
    }
    public DynamicXMLNode(String name)
    {
        node = new XElement(name);
    }
    public override bool TrySetMember( SetMemberBinder binder, object value)
    {
        XElement setNode = node.Element(binder.Name);
        if (setNode != null)
            setNode.SetValue(value);
        else
       
{
            if (value.GetType() == typeof(DynamicXMLNode))
                node.Add(new XElement(binder.Name));
            else
               
node.Add(new XElement(binder.Name, value));
        }
        return true;
    }

重写 DynamicObject 类的 TryGetMember 方法。当请求动态类的成员且未指定任何参数时,将调用 TryGetMember 方法。binder 参数包含有关被引用成员的信息,而 result 参数则引用为指定的成员返回的结果。TryGetMember 方法会返回一个布尔值,如果请求的成员存在,则返回的布尔值为 true,否则返回的布尔值为 false。
    public override bool TryGetMember( GetMemberBinder binder, out object result)
    {
        XElement getNode = node.Element(binder.Name);
        if (getNode != null)
        {
            result = new DynamicXMLNode(getNode);
            return true;
        }
        else
       
{
            result = null;
            return false;
        }
    }
public override bool TryConvert( ConvertBinder binder, out object result)
{
    if (binder.Type == typeof(String))
    {
        result = node.Value;
        return true;
    }
    else
   
{
        result = null;
        return false;
    }
}

重写 DynamicObject 类的 TryInvokeMember 方法。当使用参数请求动态类的成员时,将调用 TryInvokeMember 方法。binder 参数包含有关被引用成员的信息,而 result 参数则引用为指定的成员返回的结果。args 参数包含一个传递给成员的参数的数组。TryInvokeMember 方法会返回一个布尔值,如果请求的成员存在,则返回的布尔值为 true,否则返回的布尔值为 false。

public override bool

使用方法:.

dynamic contact = new DynamicXMLNode("Contacts");contact.Name = "Patrick Hines";contact.Phone = "206-555-0144";contact.Address = new DynamicXMLNode();contact.Address.Street = "123 Main St";contact.Address.City = "Mercer Island";contact.Address.State = "WA";contact.Address.Postal = "68402";
TryInvokeMember(
    InvokeMemberBinder binder,
    object[] args,
    out object result)
{
    Type xmlType = typeof( XElement);
    try
   
{
        result = xmlType.InvokeMember(
                  binder.Name,
                  BindingFlags.InvokeMethod |
                  BindingFlags.Public |
                  BindingFlags.Instance,
                  null, node, args);
        return true;
    }
    catch
   
{
        result = null;
        return false;
    }
}
}
/** * @brief Add a message to the first free Tx mailbox and activate the * corresponding transmission request. * @param hcan pointer to a CAN_HandleTypeDef structure that contains * the configuration information for the specified CAN. * @param pHeader pointer to a CAN_TxHeaderTypeDef structure. * @param aData array containing the payload of the Tx frame. * @param pTxMailbox pointer to a variable where the function will return * the TxMailbox used to store the Tx message. * This parameter can be a value of @arg CAN_Tx_Mailboxes. * @retval HAL status */ HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, const CAN_TxHeaderTypeDef *pHeader, const uint8_t aData[], uint32_t *pTxMailbox) { uint32_t transmitmailbox; HAL_CAN_StateTypeDef state = hcan->State; uint32_t tsr = READ_REG(hcan->Instance->TSR); /* Check the parameters */ assert_param(IS_CAN_IDTYPE(pHeader->IDE)); assert_param(IS_CAN_RTR(pHeader->RTR)); assert_param(IS_CAN_DLC(pHeader->DLC)); if (pHeader->IDE == CAN_ID_STD) { assert_param(IS_CAN_STDID(pHeader->StdId)); } else { assert_param(IS_CAN_EXTID(pHeader->ExtId)); } assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime)); if ((state == HAL_CAN_STATE_READY) || (state == HAL_CAN_STATE_LISTENING)) { //读取CAN_TST寄存器后判断TME0、1、2是否有空邮箱 /* Check that all the Tx mailboxes are not full */ if (((tsr & CAN_TSR_TME0) != 0U) || ((tsr & CAN_TSR_TME1) != 0U) || ((tsr & CAN_TSR_TME2) != 0U)) { //选择相应的邮箱并填入需要发送的数据 /* Select an empty transmit mailbox */ transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos; /* Store the Tx mailbox */ *pTxMailbox = (uint32_t)1 << transmitmailbox; /* Set up the Id */ if (pHeader->IDE == CAN_ID_STD) { hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) | pHeader->RTR); } else { hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) | pHeader->IDE | pHeader->RTR); } /* Set up the DLC */ hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC); /* Set up the Transmit Global Time mode */ if (pHeader->TransmitGlobalTime == ENABLE) { SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT); } /* Set up the data field */ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) | ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) | ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) | ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos)); WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) | ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) | ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) | ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos)); /* Request transmission */ SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM; return HAL_ERROR; } } else { /* Update error code */ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; return HAL_ERROR; } }
09-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值