• C# 关键字 out ref 真的不同


    虽然msdn里面对out和ref的解释是编译器处理不同,而且编译以后的il也确实没区别。

    但是今天在做pinvoke的时候发现out修饰的struct数据不会被marshal到c++ library。

    原因是:

    当使用ref 修饰参数的时候,生成的方法签名参数列表中该参数不会有out或in修饰,根据规范没有的话就是默认in

    当使用out修饰的时候,方法签名参数会有out修饰,这时候marshal的实现会优化,对传递的struct body数据不做封送,c++ library 得到的都是默认值(eg. 0)

    所以:

    如果callee中需要使用传入的struct数据的话,只能用ref,而不能用out。

    https://files.cnblogs.com/files/xray/ref-out.zip

    参考:

    1 The IL Assembly Language Programmers’ Reference

    in and out specify whether a managed reference or pointer parameter is used to supply input to the method, return a value from the method, or both.  If neither is specified in is assumed.

    Note: These attributes are used by Interop marshalling code: for example, if a parameter is marked both pdIn and pdOut, then its value is marshalled to the callee, and its value is marshalled back to the caller (else, pinned and referenced as an optimization)

    2 Inside Microsoft .NET IL Assembler Editor

    In/Out Parameters

    The method parameter flags in and out can be (but are not necessarily) taken into account by the marshaler. When that happens, the marshaler can optimize the process by abandoning the marshaling in one direction. By default, parameters passed by reference (including references to objects but excluding the objects) are presumed to be in/out parameters, whereas parameters passed by value (including the objects, even though managed objects are in principle references) are presumed to be in parameters. The exceptions to this rule are the [mscorlib]System.Text.StringBuilder class, which is always marshaled as in/out, and classes and arrays containing the blittable types that can be pinned—which, if the in and out flags are explicitly specified, can be two-way marshaled even when passed by value.

    Considering that managed objects don’t necessarily stay in one place and can be moved any time the garbage collector does its job, it is vital to ensure that the arguments of an unmanaged call don’t wander around while the call is in progress. This can be accomplished in the following two ways:

    • Pin the object for the duration of the call, preventing the garbage collector from moving it. This is done for the instances of formatted, blittable classes that have fixed layout in memory, invariant to managed or unmanaged code.

    • Allocate some unmovable memory. If the parameter has an in flag, marshal the data from the argument to this unmovable memory. Call the method, passing this memory as the argument. If the parameter has an out flag, marshal this memory back to the original argument upon completion of the call.

    The ILAsm syntax for explicit marshaling definition of fields and method parameters is described in Chapter 8 and in Chapter 9, “Methods.” Chapter 7, “Primitive Types and Signatures,” discusses the native types used in explicit marshaling definitions. Rather than reviewing that information here, let’s discuss some interesting marshaling cases instead.

  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/xray/p/csharp_out_ref_diff.html
Copyright © 2020-2023  润新知