混合托管C++方法并不总是向调用C#代码返回相同的结果

本文关键字:代码 调用 返回 结果 C++ 方法 混合 | 更新日期: 2023-09-27 18:27:08

C++方法在使用条件断点时返回正确的值,但在没有断点的情况下返回不正确的值。

调用C++的C#方法:

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];
            if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeDatasets[i].top))
            {
                element.PropertyId = properties[i];
                return true;
            };
        }
        return false;
    }

头文件中的C++方法:

    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;
            }
        }
    }
    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++方法:

    bool IsRayIntersectsPoly(int nPolygonIndex, Math3d::M3d RayPoints[2], CVector3D& IntersectionPoint)
{
    CMeshPolygonBase& Poly = m_PolygonArray[nPolygonIndex];
    CArrayResultI Result;
    int* pPolygonPoints = GetPolygonPoints(Poly, Result);
    Math3d::MPlane TrianglePlane;
    double Atmp[3], A;
    CVector3D* pPoints[3];
    pPoints[0] = &m_PointArray[*pPolygonPoints].m_Position;
    for(int i = 1; i < Result.GetSize() - 1; i++)
    {
        pPoints[1] = &m_PointArray[*(pPolygonPoints+i)].m_Position;
        pPoints[2] = &m_PointArray[*(pPolygonPoints+i+1)].m_Position;
        TrianglePlane.Init(*pPoints[0], *pPoints[1], *pPoints[2]);
        TrianglePlane.IntersectLine(RayPoints[0], RayPoints[1], IntersectionPoint);
        A = GetTriangleArea(*pPoints[0], *pPoints[1], *pPoints[2]);
        for(int j = 0; j < 3; j++)
        {
            Atmp[j] = GetTriangleArea(*pPoints[j], *pPoints[(j+1)%3], IntersectionPoint);
        }
        if( fabs(A - Atmp[0] - Atmp[1] - Atmp[2]) < 1.0e-5 ) return true;
    }
    return false;
};

    double GetTriangleArea(CVector3D& T1, CVector3D& T2, CVector3D& T3)
{
    double a, b, c, s;
    a = (T1 - T2).length();
    b = (T2 - T3).length();
    c = (T3 - T1).length();
    s = 0.5 * (a + b + c);
    return( sqrt(s * (s - a)* (s - b)* (s - c)) );
}

当我启动在for循环中调用SetProperty()的程序时,某些迭代器值的结果是错误的。当我在for循环中为关键迭代器值设置条件断点并遍历它时,该项的结果是可以的。可能是什么问题?

这是我发布断点的方法。例如,对于关键元素。Id==2393.

 private void StartButton_Click(object sender, EventArgs e)
    {
        DateTime startTime = DateTime.Now;
        List<Materializer> materializers = new List<Materializer>();
        List<ulong> properties = new List<ulong>();
        // Load STLs
        for (int i = 0; (int)i < (this.dataGridView.RowCount - 1); i++)
        {
            if (dataGridView.Rows[i].Cells[1].Value != null && (string)dataGridView.Rows[i].Cells[1].Value != "")
            {
                Materializer materializer = new Materializer();
                materializer.LoadSTLMesh(dataGridView.Rows[i].Cells[0].Value.ToString());
                materializers.Add(materializer);
                properties.Add((ulong)dataGridView.Rows[i].Cells[1].Tag);                
            }
         }
        CreatePentalTrees(materializers);
        int processedElementCount = 0;
        int changedElementCount = 0;
        // Loop over elements
        foreach (Element element in model.ElementsList.Values)
            if ((element.Topology == 7 || element.Topology == 8) && !lockedProperties.ContainsKey(element.PropertyId)) // 3D elements only
            {

                Node center = this.CenterPoint(element, model.NodesList);
                if (element.Id == 2393)
                {
                    //if breakpoints thats ok, else not ok
                    Console.WriteLine(element.Id);
                    Console.WriteLine(element.PropertyId);
                }
                if (SetProperty(element, center, materializers, properties))   // Check for center point
                {
                    //changedElements.Add(element.Id, true);
                    changedElementCount++;
                }
                else
                {
                    // Check for all nodes if center point does not belong to any STL
                    int[] nodeOrder;
                    switch (element.Topology)
                    {
                        case 7:
                            nodeOrder = wedgeNodeOrder;
                            break;
                        case 8:
                            nodeOrder = brickNodeOrder;
                            break;
                        default:
                            throw new Exception("Unknown topology " + element.Topology.ToString());
                    }
                    for (int i = 0; i < nodeOrder.Length; i++)
                    {
                        Node node = model.NodesList[element.NodeIds[nodeOrder[i]]];
                        if (SetProperty(element, node, materializers, properties))
                        {
                            //changedElements.Add(element.Id, true);
                            changedElementCount++;
                            break;
                        }
                    }
                }
                if (++processedElementCount % 100 == 0)
                {
                    labelTime.Text = "Changed/processed elements: " + changedElementCount.ToString() + "/" + processedElementCount.ToString();
                    labelTime.Refresh();
                    Application.DoEvents();
                }
            }
        DateTime endTime = DateTime.Now;
        labelTime.Text = "Total time: " + (endTime - startTime).TotalSeconds.ToString() + " s";
        MessageBox.Show("Completed.");
        SaveFileDialog saveFileDlg = new SaveFileDialog();
        saveFileDlg.Title = "Save FEMAP neutral file";
        saveFileDlg.Filter = "(*.neu)|*.neu";
        if (saveFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            FemapNeutral.ExportNeu(saveFileDlg.FileName, model);
        }
    }

混合托管C++方法并不总是向调用C#代码返回相同的结果

您似乎调用了许多未列出的方法,和/或代码墙让我迷失了方向。添加这些代码并没有帮助:将您的问题简化为一个更简单的问题,以证明问题可能存在。

但是,如果您有非托管代码读取托管数据,则最有可能的原因是在使用托管代码之前未能封送或固定数据。

垃圾收集器可能会以意想不到的方式移动未固定的数据。