P/Invoke封送和反封送C#和非托管DLL之间的二维数组、结构和指针
具有、和的包装器,但没有可用的C#包装器。我正在尝试围绕从下载的P/Invoke封送和反封送C#和非托管DLL之间的二维数组、结构和指针,c#,python,c++,pinvoke,marshalling,C#,Python,C++,Pinvoke,Marshalling,具有、和的包装器,但没有可用的C#包装器。我正在尝试围绕从下载的flann.dll32位非托管dll创建一个C#包装器 作为PInvoke/marshalling的新手,我很确定我没有正确地执行对DLL的C#p/Invoke调用。我基本上是想用C#来反映可用的。混淆的主要方面有: 我不知道如何在C#中的2D托管矩形数组之间封送(输入)和解组(输出),其中参数类型为float*,即指向中存储的查询集的指针(根据中的注释) 我也不确定如何将结构引用传递给C是否正确,即struct FLANNPar
flann.dll
32位非托管dll创建一个C#包装器
作为PInvoke/marshalling的新手,我很确定我没有正确地执行对DLL的C#p/Invoke调用。我基本上是想用C#来反映可用的。混淆的主要方面有:
- 我不知道如何在C#中的2D托管矩形数组之间封送(输入)和解组(输出),其中参数类型为
,即指向中存储的查询集的指针(根据中的注释)float*
- 我也不确定如何将结构引用传递给C是否正确,即
struct FLANNParameters*
是否适合引用IntPtr
和typedef void*
int*索引
我需要使用的公共导出C++方法如下:< /P>
typedef void*FLANN_索引;/*不赞成*/
类型定义无效*法兰索引;
法兰导出外部结构法兰参数默认法兰参数;
//dataset=指向按行主顺序存储的查询集的指针
法兰导出法兰索引法兰构建索引(浮点*数据集,
int行,
int cols,
浮动*加速,
结构法兰参数*法兰参数);
法兰出口法兰自由索引(法兰索引索引id,
结构法兰参数*法兰参数);
FLANN_导出int FLANN_查找最近邻(浮点*数据集,
int行,
int cols,
浮点*测试集,
int trows,
整数*指数,
浮动*距离,
int nn,
结构法兰参数*法兰参数);
托管C#包装器(我的实现)
这是我基于上述公开方法的C#包装器
NativeMethods.cs
使用系统;
使用System.Runtime.InteropServices;
名称空间FlannWrapper
{
///
//方法在本地非托管C++ DLL与托管C语言之间映射
///正在尝试镜像:https://github.com/mariusmuja/flann/blob/master/src/cpp/flann/flann.h
///
公共类本地方法
{
///
///从获取的32位flann dllhttp://sourceforge.net/projects/pointclouds/files/dependencies/flann-1.7.1-vs2010-x86.exe/download
///
公共常量字符串DllWin32=@“C:\ProgramFiles(x86)\flann\bin\flann.dll”;
///
///C++:flann_index_t flann_build_index(float*dataset、int行、int列、float*speedup、FLANNParameters*flann_参数)
///
[DllImport(DllWin32,EntryPoint=“flann\u build\u index”,CallingConvention=CallingConvention.Cdecl,SetLastError=true)]
公共静态外部IntPtr flannBuildIndex([In][marshallas(UnmanagedType.LPArray,ArraySubType=UnmanagedType.R4)]float[,]dataset,//?[In]IntPtr dataset???
int行,int列,
参考浮点数加速比,/???
[In]参考法兰参数法兰参数(法兰参数);/???
///
///C++:int-flann_-free_索引(flann_-index_-t-index_-ptr,FLANNParameters*flann_参数)
///
[DllImport(DllWin32,EntryPoint=“flann\u free\u index”,CallingConvention=CallingConvention.Cdecl,SetLastError=true)]
公共静态外部intflannfreeIndex(IntPtr indexPtr,/?)???
[In]ref FlannParameters flannapams);/?[In,marshallas(UnmanagedType.LPStruct)]FlannParameters flannapams;
///
///C++:int-flann\u-find\u-neights\u-neights\u-index\u-ptr、float*testset、int-tcount、int*result、float*dists、int-nn、FLANNParameters*flann参数
///
[DllImport(DllWin32,EntryPoint=“flann\u find\u neights\u neights\u index”,CallingConvention=CallingConvention.Cdecl,SetLastError=true)]
公共静态外部int flannFindNearestNeighborsIndex(IntPtr indexPtr,/?)???
[In][marshallas(UnmanagedType.LPArray,ArraySubType=UnmanagedType.R4)]float[,]testset,/?[In]IntPtr数据集???
int t计数,
[Out]IntPtr result,//?[Out][marshallas(UnmanagedType.LPArray,ArraySubType=UnmanagedType.R4)]int[,]result,
[Out]IntPtr距离,/???
int nn,
[In]参考法兰参数法兰参数(法兰参数);/???
}
}
弗兰内斯特酒店
使用系统;
使用System.IO;
使用System.Runtime.InteropServices;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
名称空间FlannWrapper
{
[测试类]
公共类法兰斯特:IDisposable
{
私人IntPtr curIndex;
受保护法兰参数法兰参数;
//受保护的GCHandle GCHandle;
[测试初始化]
public void TestInitialize()
{
this.curIndex=IntPtr.Zero;
//初始化法兰参数
this.flannParams=新的FlannParameters();//使用默认值
this.flannapams.algorithm=FlannAlgorithmE
?result2D
{int[2, 3]}
[0, 0]: 7078010
[0, 1]: 137560165
[0, 2]: 3014708
[1, 0]: 3014704
[1, 1]: 3014704
[1, 2]: 48
?dists2D
{float[2, 3]}
[0, 0]: 2.606415E-43
[0, 1]: 6.06669328E-34
[0, 2]: 9.275506E-39
[1, 0]: 1.05612418E-38
[1, 1]: 1.01938872E-38
[1, 2]: 1.541428E-43
Result:
[[0 1 2]
[2 1 0]]
Dists:
[[ 5.00000000e+00 2.48000000e+02 2.04440000e+04]
[ 6.64000000e+02 1.28500000e+04 1.59910000e+04]]
static void Main(string[] args)
{
int rows = 3, cols = 5;
int tCount = 2, nn = 3;
float[,] dataset2D = { { 1.0f, 1.0f, 1.0f, 2.0f, 3.0f},
{ 10.0f, 10.0f, 10.0f, 3.0f, 2.0f},
{ 100.0f, 100.0f, 2.0f, 30.0f, 1.0f} };
float[,] testset2D = { { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f},
{ 90.0f, 90.0f, 10.0f, 10.0f, 1.0f} };
var fparams = new FlannParameters();
var index = NativeMethods.flannBuildIndex(dataset2D, rows, cols, out float speedup, ref fparams);
var indices = new int[tCount, nn];
var idists = new float[tCount, nn];
NativeMethods.flannFindNearestNeighborsIndex(index, testset2D, tCount, indices, idists, nn, ref fparams);
NativeMethods.flannFreeIndex(index, ref fparams);
}
[DllImport(DllWin32, EntryPoint = "flann_build_index", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr flannBuildIndex(float[,] dataset,
int rows, int cols,
out float speedup, // out because, it's and output parameter, but ref is not a problem
ref FlannParameters flannParams);
[DllImport(DllWin32, EntryPoint = "flann_free_index", CallingConvention = CallingConvention.Cdecl)]
public static extern int flannFreeIndex(IntPtr indexPtr, ref FlannParameters flannParams);
[DllImport(DllWin32, EntryPoint = "flann_find_nearest_neighbors_index", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern int flannFindNearestNeighborsIndex(IntPtr indexPtr,
float[,] testset,
int tCount,
[In, Out] int[,] result, // out because it may be changed by C side
[In, Out] float[,] dists,// out because it may be changed by C side
int nn,
ref FlannParameters flannParams);
[StructLayout(LayoutKind.Sequential)]
public struct FlannParameters
{
public FlannAlgorithmEnum algorithm;
public int checks;
public float eps;
public int sorted;
public int maxNeighbors;
public int cores;
public int trees;
public int leafMaxSize;
public int branching;
public int iterations;
public FlannCentersInitEnum centersInit;
public float cbIndex;
public float targetPrecision;
public float buildWeight;
public float memoryWeight;
public float sampleFraction;
public int tableNumber;
public int keySize;
public int multiProbeLevel;
public FlannLogLevelEnum logLevel;
public int randomSeed;
}