试图实现一个 C++ 库,需要一些关于如何与它交互的指针

Posted

技术标签:

【中文标题】试图实现一个 C++ 库,需要一些关于如何与它交互的指针【英文标题】:Attempting to implement a C++ library, need some pointers on how to interface with it 【发布时间】:2020-10-06 01:56:42 【问题描述】:

我在 C++ 方面相对缺乏经验,正在尝试将库编译为 DLL 以在 Unity 中使用。至于生成 DLL 并与之交互,我已经成功地让下面的函数在 Unity 中调用并返回一个虚拟值,不用担心。

我正在努力研究如何与这个Approximate Nearest Neighbour 库交互,并且可以使用一些指针。 (如果不下载上面链接的源代码并自己看一下,这可能是一个很难定义的问题,但我会尽量简化)

在 Unity 中,我有一个三维数组(points[] = float[x,y,z])和一个空间中的查询点(float[x,y,z])。我希望将这些数据输入到类似下面的函数中(我已从 ann_sample.cpp 修改 - 原始链接在底部),并将最近的邻居返回到这一点。

我的功能

int myInit(float x, float y, float z, int numPoints, int maxPoints, int nn)

    int                 nPts;                   
    ANNpointArray       dataPts;                
    ANNpoint            queryPt;                
    ANNidxArray         nnIdx;                  
    ANNdistArray        dists;                  
    ANNkd_tree* kdTree;                         

    int dimension = 3;
    
    queryPt = annAllocPt(dimension , x);                        //This only expects the dimension, and a coord - I assume this is pre-allocation? 
    dataPts = annAllocPts(maxPoints, dimension);    //Again, this does not expect the coordinate (xyz) data, is pre-allocating the array?
    nnIdx = new ANNidx[nn];                         // more pre-allocating?
    dists = new ANNdist[nn];                        // more pre-allocating?

    nPts = numPoints;           
                        
    //Should we be populating the actual queryPt and dataPts here?
    //at the moment, these are still empty?

    kdTree = new ANNkd_tree(                    // build search structure
        dataPts,                                // the data points
        nPts,                                   // number of points
        dimension);                             // dimension of space


    kdTree->annkSearch(                     // search
            queryPt,                        // query point
            nn,                             // number of near neighbors
            nnIdx,                          // nearest neighbors (returned)
            dists,                          // distance (returned)
            eps);                           // error bound
    
    annClose();                                 // done with ANN

    return nnIdx[0];  //this is the nearest neighbor  

原始函数 (这需要命令行输入 - 即 ann_sample [-d dim] [-max mpts] [-nn k] [-e eps] [-df data] [-qf query])

int main(int argc, char **argv)

    int                 nPts;                   // actual number of data points
    ANNpointArray       dataPts;                // data points
    ANNpoint            queryPt;                // query point
    ANNidxArray         nnIdx;                  // near neighbor indices
    ANNdistArray        dists;                  // near neighbor distances
    ANNkd_tree*         kdTree;                 // search structure

    getArgs(argc, argv);                        // read command-line arguments

    queryPt = annAllocPt(dim);                  // allocate query point
    dataPts = annAllocPts(maxPts, dim);         // allocate data points
    nnIdx = new ANNidx[k];                      // allocate near neigh indices
    dists = new ANNdist[k];                     // allocate near neighbor dists

    nPts = 0;                                   // read data points

    cout << "Data Points:\n";
    while (nPts < maxPts && readPt(*dataIn, dataPts[nPts])) 
        printPt(cout, dataPts[nPts]);
        nPts++;
    

    kdTree = new ANNkd_tree(                    // build search structure
                    dataPts,                    // the data points
                    nPts,                       // number of points
                    dim);                       // dimension of space

    while (readPt(*queryIn, queryPt))          // read query points
        cout << "Query point: ";                // echo query point
        printPt(cout, queryPt);

        kdTree->annkSearch(                     // search
                queryPt,                        // query point
                k,                              // number of near neighbors
                nnIdx,                          // nearest neighbors (returned)
                dists,                          // distance (returned)
                eps);                           // error bound

        cout << "\tNN:\tIndex\tDistance\n";
        for (int i = 0; i < k; i++)            // print summary
            dists[i] = sqrt(dists[i]);          // unsquare distance
            cout << "\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << "\n";
        
    
    delete [] nnIdx;                            // clean things up
    delete [] dists;
    delete kdTree;
    annClose();                                 // done with ANN

    return EXIT_SUCCESS;


正如您在我的 cmets 中看到的那样,我无法确定将输入数据实际输入的位置和方式,即我上面提到的点数组。

似乎正在使用以下代码填充数据(在参考函数中),通过使用“istream”类,但我不明白它是如何工作的,或者我将如何模拟它。

    while (nPts < maxPts && readPt(*dataIn, dataPts[nPts])) 
        printPt(cout, dataPts[nPts]);
        nPts++;
    

... 

bool readPt(istream &in, ANNpoint p)            // read point (false on EOF)

    for (int i = 0; i < dim; i++) 
        if(!(in >> p[i])) return false;
    
    return true;

【问题讨论】:

Why are fellow users removing thank-you's from my questions? 【参考方案1】:

更新: 写完这一切显然是我需要朝着正确方向前进的动力!如果它与将来的任何人相关,我与之交互的方式相当简单。

我将一些 2D 数组传递到 C++ 插件中,然后将其转换为 ANNpointArrays。鉴于它是 C++,我需要先实例化适当大小的数组,然后填充如下:

    float qPoints[][3]

    .....

    for (int i = 0; i < nQueryPts; i++) 
        for (int j = 0; j < dimension; j++)
        
            queryPts[i][j] = qPoints[i][j];
        
    

一旦我有了这个,在我的每个查询点上运行 annKSearch 就相对简单了,返回最近邻的整数数组,并为距离浮动。我需要学习一些关于如何在 C++ 中传递和实例化数组的知识,但这比我想象的要容易得多!

并不是说有人在读它——但这对我来说是一个有用的练习,我把这个问题留了下来,以防其他人试图在 C# 中实现这个库!

【讨论】:

以上是关于试图实现一个 C++ 库,需要一些关于如何与它交互的指针的主要内容,如果未能解决你的问题,请参考以下文章

如何正确包含来自 NVIDIA C++ 标准库的文件?

ZeroMQ:如何实现客户端通知?

实现 COM 接口 C++ / VC++ 6.0 / MFC

如何正确安装 c++ cpr

如何在 C++ 共享库中隐藏业务对象的实现细节并提供接口

C++ LRU 缓存 - 需要有关如何提高速度的建议