请查看以下c#代码:
double* ptr;
fixed(double* vrt_ptr = &vertices[0])
{
fixed(int* tris_ptr = &tris[0])
{
ptr = compute(vrt_ptr, 5, (double*)tris_ptr, 5);
// compute() is a native C++ function
}
}
Debug.Log("Vertices Recieved: " + *ptr);
/* and so on */
我从* ptr获得垃圾值。我怀疑由ptr
分配给compute
的数组不会保留在外部固定块之外。是这样吗??或者是由于其他一些问题?
答案 0 :(得分:3)
这是不有效代码,垃圾收集器只能更新vrt_ptr
和tris_ptr
变量的值。但是非托管代码使用这些指针的 copy ,GC无法更新副本的值。因此,如果在非托管代码运行时发生,则可能发生垃圾收集,例如当程序中的其他线程触发集合时,非托管代码将通过指针副本读取垃圾数据。很难诊断,经常不会发生。
你必须固定顶点和tris数组。在您的情况下,pinvoke marshaller已经完成了,只需直接传递数组而不使用 fixed 。修正:
double* ptr = compute(vertices, 5, tris, 5);
相应地调整pinvoke声明,用double []替换double *。
您现在还必须处理您首先编写此代码的可能原因。有没有的场景,其中将int []转换为double []是有效的,这可能是因为你在GC灾难发生之前就得到了垃圾结果。如果由于某种原因无法更新 tris 的声明,则必须在通话前创建一个double []。