所以我有一个包含许多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#代码(进出)中可用?
答案 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 = ¢er[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 = ¢er[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 程序集中定义,因此在这两种情况下,您都不会提取任何其他依赖项。