在托管代码和非托管代码之间传递结构

本文关键字:结构 之间 非托管代码 托管代码 | 更新日期: 2023-09-27 18:27:12

我在此方法中从c#调用c++/cli方法:

        bool SetProperty(Element element, Node referencePoint, List<Materializer> materializers, List<ulong> properties)
    {
        // Loop over STLs
        for (int i = 0; i < materializers.Count; i++)
        {               
            Materializer materializer = materializers[i];
            PentalTreeNode pentalTreeRoot = pentalTreeDatasets[i].top;

            if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeRoot))
            {
                element.PropertyId = properties[i];
                return true;
            };
        }
        return false;
    }

C++/cli方法是这样的:

bool IsPointInside(double x, double y, double z, PentalTreeNode ^root)
    {
        int intersectionCount = 0;
        Math3d::M3d rayPoints[2], intersectionPoint;
        rayPoints[0].set(x,y,z);
        rayPoints[1].set(x,y,1.0e6);

        if(_box->IsContainingPoint(x,y,z))
        {           
            intersectionCount=CountIntersects(x,y,z,root);
            return (intersectionCount%2!=0);
        }   
    }

c++/cli方法不总是返回相同的结果,这有什么错?如何固定或封送?

c++/cli中的方法(也许这不好?):

int CountIntersects(double x, double y, double z, PentalTreeNode ^root)
    {
        Math3d::M3d rayPoints[2], intersectionPoint;
        rayPoints[0].set(x,y,z);
        rayPoints[1].set(x,y,1.0e6);
        if(!root) 
            return 0;
        else
        {
            int special = CountIntersects(x,y,z,root->special);
            if (x <= root->xMax && x >= root->xMin && y <= root->yMax && y >= root->yMin)
            {
                if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
                {
                    return (1 + special);
                }
                else 
                    return special;
            }
            else
            {
             if (y>root->yMax)
              {
                    return (CountIntersects(x,y,z,root->top)+special);
              }
              else if(y<root->yMin)
                    {
                        return (CountIntersects(x,y,z,root->bottom)+special);
                    }
                    else if(x<root->xMin)
                            {
                                return (CountIntersects(x,y,z,root->left)+special);
                            }
                            else if(x>root->xMax)
                            {
                                return (CountIntersects(x,y,z,root->right)+special);
                            }
                            else 
                                return special;
            }
        }
    }

在托管代码和非托管代码之间传递结构

if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))

这个特殊的语句中可能有一个缺陷,您从未初始化intersectionPoint。C++可以让你逃脱惩罚,它没有任何类似于C#的明确赋值规则。这是否是真正的问题还不是100%清楚,变量可能是通过引用传递的。

在Debug内部版本中,这样一个未初始化的变量将具有可预测的值。当您将调试器切换到十六进制显示模式时,可以很容易地在调试器中看到这些内容。此结构或类中的字段将包含值0xcccccccc,该值很容易生成无意义的结果,或者由于访问冲突而导致代码崩溃。在Release版本中,/RTC选项没有打开,您将在变量中获得完全随机的值。

这与你对问题的描述非常吻合,所以很有可能这就是问题所在。一定要使用调试器来查找类似这样的问题,当您单步执行代码时,您可以使用自动调试器窗口轻松地查看局部变量的值。

您不是在调用C++方法!您正在调用一个C++/CLI方法。因此,它是普通的.NET代码,并且总是正确传递。在这种情况下,没有必要在C#中固定或封送任何东西!

如果返回的值不是预期值,则应尝试在C++/CLI项目中查找问题。