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;

C# から呼び出し可能にするには、CLI ラッパーで tham をどのようにラップすればよいのでしょうか? ここで私の主な関心事はconst float* center[(x, y, z)] ポインターです - C# でそのようなフォームを作成する方法、C# で tham を取得する方法は? float*では、一般的に、C# コードで (内外で) 利用可能にするために CLI コードで作業する方法は?

4

3 に答える 3

3

他の2つの回答をフォローアップすると、実際のコードは次のようになります

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_ptrて GC からロックする必要があります。

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 に答える