【问题标题】:Passing Structures between Managed and Unmanaged Code在托管代码和非托管代码之间传递结构
【发布时间】:2013-08-10 09:48:29
【问题描述】:

我在这个方法中从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;
            }

        }

    }

【问题讨论】:

    标签: c# c++ visual-studio-2010 c++-cli


    【解决方案1】:
    if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
    

    这个特定的语句有一个可能的缺陷,你从来没有初始化过intersectionPoint。 C++ 可以让你摆脱这一点,它没有任何类似于 C# 的明确分配规则的东西。不是 100% 清楚这是否是真正的问题,变量可能是通过引用传递的。

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

    这与您对问题的描述非常吻合,因此很有可能确实是问题所在。一定要使用调试器来发现这样的问题,您可以在单步执行代码时通过 Autos 调试器窗口轻松查看局部变量的值。

    【讨论】:

    • 非常感谢,这是一个解决方案。谢谢你的解释。
    【解决方案2】:

    您没有调用 C++ 方法!您正在调用 C++/CLI 方法。因此它是正常的 .NET 代码,并且总是正确传递。在这种情况下,无需在 C# 中固定或编组任何内容!

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

    【讨论】:

    • 我再次从 c++/cli 添加了方法...查看编辑的问题...谢谢!
    • 我不明白你的目标或算法......但是将值传递给 C++/CLI 没有问题,所以答案是正确的。如果您对算法还有其他问题,您应该创建一个新问题...
    • 好的,将值传递给 c++/cli 没有问题。谢谢你。在两个 c++/cli 方法之间传递值有问题吗?
    • 不...这也不是这里的问题...至少从您显示的代码来看。我认为你的算法不是它应该的。您可以通过单元测试轻松地对其进行测试!
    • 算法没问题...我在 for 循环中调用 c# 方法,对于某些迭代器值,结果是错误的...当我为该迭代器值设置断点时,结果是可以的!当我启动没有断点的程序时,某些迭代器值的结果是错误的......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2011-11-01
    相关资源
    最近更新 更多