c# - MSIL 存储要返回的结构的值

标签 c# .net cil il

我正在使用 RemotingLite 库 ( see at github ),并且代理类工厂存在问题。 简而言之,问题在于生成返回 ValueType 对象(如用户定义的结构)的代码时。

这里是原始代码的一部分:

...
mIL.Emit(OpCodes.Ldloc, resultLB.LocalIndex); //load the result array
mIL.Emit(OpCodes.Ldc_I4, 0); //load the index of the return value. Alway 0
mIL.Emit(OpCodes.Ldelem_Ref); //load the value in the index of the array

if (returnType.IsValueType)
{
    mIL.Emit(OpCodes.Unbox, returnType); //unbox it
    mIL.Emit(ldindOpCodeTypeMap[returnType]);
}
else
    mIL.Emit(OpCodes.Castclass, returnType);
}
        mIL.Emit(OpCodes.Ret);

ldindOpCodeTypeMap 是一个包含诸如 OpCodes.Ldind_U2 等操作码的字典。因此它仅适用于标准 MSIL 类型,例如 Int16、Int32 等。但是,如果我需要压入堆栈然后返回自定义 ValueType 值(例如 - Guid - 大小为 16 字节),我需要做什么?

例如:

...
mIL.Emit(OpCodes.Unbox, returnType); //unbox it
OpCode opcode;
if (ldindOpCodeTypeMap.TryGetValue(returnType, out opcode))
{
    mIL.Emit(ldindOpCodeTypeMap[returnType]);
}
else
{
    // here I getting the size of custom type
    var size = System.Runtime.InteropServices.Marshal.SizeOf(returnType);
    // what next?
}
...

这里我得到了自定义ValueType值的大小。那么如何像 Ldind_x 操作码那样间接将自定义 ValueType 的值加载到计算堆栈上呢? 谢谢!

最佳答案

Ldobj 会做你想做的事。但您也可以用 Unbox_Any 替换整个条件:它将执行值类型或引用类型所需的所有操作。

您发布的代码的完整替换是:

...
mIL.Emit(OpCodes.Ldloc, resultLB.LocalIndex); //load the result array
mIL.Emit(OpCodes.Ldc_I4, 0); //load the index of the return value. Alway 0
mIL.Emit(OpCodes.Ldelem_Ref); //load the value in the index of the array

mIL.Emit(OpCodes.Unbox_Any, returnType);
mIL.Emit(OpCodes.Ret);

关于c# - MSIL 存储要返回的结构的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30967286/

相关文章:

c# - MVC - Ajax POST 后 PartialView 未更新

c# - 使用具有预加载功能的内存数据库对 EF Core 进行单元测试

.net - Autofac注册通过方法解决

c# - 有没有办法查看 DynamicMethod 生成的 x86 汇编代码?

c# - 以编程方式验证电子邮件已到达交换邮箱

c# - 继承自 FileSystemWatcher

c# - XML反序列化泛型方法

.net - 为什么没有 .NET RuntimePropertyHandle 和 PropertyInfo.GetPropertyFromHandle?

c# - 如何从 PEVerify 诊断 "Type load failed"

c# - 如何访问不在Resources文件夹根目录下的资源文件? (共享点 2010)