如何将C ++代码包装到具有大量浮点*(表示点)的CLI中?

时间:2013-03-04 15:36:25

标签: c# c++ .net c++-cli wrapper

所以我有一个包含许多C风格函数的库,描述为:

/// Finds the polygon nearest to the specified center point.
///  @param[in]     center      The center of the search box. [(x, y, z)]
///  @param[in]     extents     The search distance along each axis. [(x, y, z)]
///  @param[in]     filter      The polygon filter to apply to the query.
///  @param[out]    nearestRef  The reference id of the nearest polygon.
///  @param[out]    nearestPt   The nearest point on the polygon. [opt] [(x, y, z)]
/// @returns The status flags for the query.
dtStatus findNearestPoly(const float* center, const float* extents,
                         const dtQueryFilter* filter,
                         dtPolyRef* nearestRef, float* nearestPt) const;

我想知道如何在我的CLI包装器中包装tham以使C#可调用?这里我的主要内容是const float* center,它是[(x,y,z)]指针 - 如何在C#中形成这样的,如何在C#中输出?那么一般来说如何在CLI代码中使用float*来使其在C#代码(进出)中可用?

3 个答案:

答案 0 :(得分:3)

跟进另外两个答案,这是一些实际代码可能是什么样的

Poly.cpp (C ++ / CLI)

#include "stdafx.h"
#include "Poly.h"

#include "findNearestPoly.h"

using namespace System;

namespace CStyleArrays
{
    public ref class Poly abstract sealed // "abstract sealed" = static
    {
    public:
        static int FindNearest(Tuple<float, float, float>^ center, Tuple<float, float, float>^ extents,
            [Runtime::InteropServices::Out] Tuple<float, float, float>^% nearestPt) {
                const float pCenter[] = { center->Item1, center->Item2, center->Item3};
                const float pExtents[] = { extents->Item1, extents->Item2, extents->Item3};
                float pNearestPt[3];

                int retval = findNearestPoly(pCenter, pExtents, nullptr /*filter*/, nullptr /*nearestRef*/, pNearestPt);
                // if (retval == success)
                {
                    nearestPt = Tuple::Create(pNearestPt[0], pNearestPt[1], pNearestPt[2]);
                }

                return retval;
        }

        static int FindNearest(cli::array<float>^ center, cli::array<float>^ extents, cli::array<float>^% nearestPt) {
        if ((center->Length != 3) || (extents->Length != 3) || (nearestPt->Length != 3))
            throw gcnew ArgumentOutOfRangeException();

            const pin_ptr<float> pinCenter = &center[0]; // "... if any element of an array is pinned, then the whole array is also pinned ..."
            const float* pCenter = pinCenter;
            const pin_ptr<float> pinExtents = &extents[0];
            const float* pExtents = pinExtents;
            const pin_ptr<float> pinNearestPt = &nearestPt[0];
            float* pNearestPt = pinNearestPt;

        return findNearestPoly(pCenter, pExtents, nullptr /*filter*/, nullptr /*nearestRef*/, pNearestPt);
        }
    };
}

示例C#将是

namespace TestCStyleArrays
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                var center = Tuple.Create(0f, 1f, 2f);
                var extents = Tuple.Create(10f, 20f, 30f);
                Tuple<float, float, float> nearestPt;
                CStyleArrays.Poly.FindNearest(center, extents, out nearestPt);
            }

            {
                var center = new[] { 0f, 1f, 2f };
                var extents = new[] { 10f, 20f, 30f };
                var nearestPt = new float[3];
                CStyleArrays.Poly.FindNearest(center, extents, ref nearestPt);
            }
        }
    }
}

答案 1 :(得分:2)

要添加到@ Serious的帖子,示例函数原型可能是:

dtStatus findNearestPoly(array<float> ^center, 
                         array<float> ^extents, 
                         array<dtQueryFilter> ^filter,
                         [out] dtPolyRef %nearestRef,
                         [out] array<float> ^%nearestPt) const;

对于这个例子,我假设dtQueryFilter,dtStatus和dtPolyRef是枚举或其他一些直接可通过的类型。如果它们是类,则需要创建合适的ref类,引用将包含^指针。

然后,要使用数组数据,您需要使用pin_ptr将其锁定在GC中:

pin_ptr<float> ppf = &center[0];
float *pCenter = ppf;

注意,要使用[out]参数,您必须:

using namespace System::Runtime::InteropServices;  

答案 2 :(得分:0)

使用简单的 cli :: array&lt; float&gt; Tuple&lt; float,float,float&gt; http://msdn.microsoft.com/en-us/library/dd383822.aspx

元组 mscorlib 程序集中定义,因此在这两种情况下,您都不会提取任何其他依赖项。