3

所以我有一个库,其中包含许多 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;

我想知道如何将 tham 包装在我的 CLI 包装器中以使 C# 可调用?在这里,我的主要兴趣是const float* center[(x, y, z)] 指针 - 如何在 C# 中形成这样的指针,如何在 C# 中将其取出?那么通常如何float*在 CLI 代码中使用以使其在 C# 代码中可用(输入和输出)?

4

3 回答 3

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);
            }
        }
    }
}
于 2013-03-04T22:13:41.400 回答
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_ptrGC 锁定它们:

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

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

using namespace System::Runtime::InteropServices;  
于 2013-03-04T21:14:28.133 回答
0

使用简单的cli::array<float>Tuple<float,float,float> :http : //msdn.microsoft.com/en-us/library/dd383822.aspx

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

于 2013-03-04T15:57:50.370 回答