如果我有像
这样的c#代码[DllImport("SomeDll")]
private static extern void passAClass(ClassType myClass);
并将其称为
ClassType myClass = new ClassType();
passAClass(myClass);
我可以看到类(它的数据段)作为指针传递给dll,但我不确定运行时是否将类数据从其位置复制到新内存中,然后将指针传递给新内存,或者它直接传递指向类的内存位置的指针。
我可以看到,如果dll更改了内存中的数据,它会收到一个指针,在调用之后c#中可以看到更改,但这可能是因为它将另一个内存副本重新放回到托管类的位置存储。
答案 0 :(得分:1)
但这可能是因为它还有另一份内存副本
不,这不是自动的,你明确地必须给参数赋予[Out]属性以确保它复制回来。您确实在没有属性的情况下看到更改的事实证明该类是 blittable 。换句话说,班级'字段都是简单的值类型,它们没有被CLR重新排列。因此托管布局与非托管布局相同,允许pinvoke编组器固定对象并传递指针。
这并不罕见。最好不要让它成为一个意外,例如,当您将本机代码移植到x64时,您可能会在生命中失去一天。为类提供[StructLayout]属性以确保顺序布局是一个好主意。