Getfield.SetValue不起作用

时间:2014-12-01 10:50:18

标签: c# reflection pinvoke

在我的项目中我目前正在研究我偶然发现了这个问题:

我想创建一个Class" ApiID"的实例。我从Reflector获得了代码,因为你可以看到.dll(不是我的Project)导入来自ummanaged代码,我无法访问。

    [StructLayout(LayoutKind.Sequential, Size=0x10), CLSCompliant(false), NativeCppClass, DebugInfoInPDB, MiscellaneousBits(0x40)]
public struct ApiId
{
    private long <alignment member>;
    public static unsafe void <MarshalCopy>(ApiId* idPtr1, ApiId* idPtr2)
    {
        ApiId.{ctor}(idPtr1, (ApiId modopt(IsConst)* modopt(IsImplicitlyDereferenced)) idPtr2);
    }

    public static unsafe void <MarshalDestroy>(ApiId* idPtr1)
    {
        ApiId.{dtor}(idPtr1);
    }
}

我的C#-Code看起来像这样:

var _apiId = new ApiId();
long vlue = 0x0000000041403070;
typeof(ApiId).GetField("<alignment member>", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(_apiId, vlue);

守则成功运行,但战场不会改变并保持0 ...我做错了什么? 问候

1 个答案:

答案 0 :(得分:6)

这里的问题是拳击

这一行:

typeof(ApiId).GetField("<alignment member>", ...).SetValue(_apiId, vlue);

将在_apiId中装入struct值并设置装箱副本的字段值。它不会改变原作。

FieldInfo.SetValue的定义如下:

public void SetValue(
    Object obj,
    Object value
)

因此,第一个参数,您的_apiId将被装箱。拳击将复制结构值。因此,SetValue将更改盒装副本而不是原始副本。

相反,您可以自己装箱:

object apiId = new ApiId();
long vlue = ...
typeof(ApiId)...
_apiId = (ApiId)apiId;

这是一个展示的.NET Fiddle。尝试更改注释掉哪一行以查看差异。