从C崩溃应用程序使用全球C++对象
这是我的第一篇文章,我是这个网站的新手,但我一直潜伏了一段时间。我对C有很好的了解,并且对C++的知识非常有限。我猜。我在Windows(XPx64),VS2008上。从C崩溃应用程序使用全球C++对象
我想包装一个C++库kdtree2,以便我可以从C中使用它。主要问题与访问kdtree2和kdtree2_result_vector类有关。由于作者ftp服务器没有响应我已经上传了一份原始发行版本kdtree2 src
只需在kd-tree(二叉树的一种形式)上的一些快速信息,“'数据'是n中的坐标 - 维笛卡尔空间和索引,它用于最近邻搜索,因此在构造树(不会被修改)之后,可以查询树的各种类型的nn搜索,在这种情况下的结果是在结构(C状结构)的矢量对象返回。
struct kdtree2_result {
//
// the search routines return a (wrapped) vector
// of these.
//
public:
float dis; // its square Euclidean distance
int idx; // which neighbor was found
};
我的想象溶液具有kdtree2对象(每线程)的阵列。对于kdtree2_result_vector类我没有得到的溶液还就像我一样没有通过第一个基地。 没有必要直接访问kdtree2类。
我只需要填充数据然后使用它(因为下面的第二个函数是一个例子)。为此,我已经定义:
kdtree2 *global_kdtree2;
extern "C" void new_kdtree2 (float **data, const int n, const int dim, bool arrange) {
multi_array_ref<float,2> kdtree2_data ((float *) &data [ 0 ][ 0 ], extents [ n ][ dim ], c_storage_order ());
global_kdtree2 = new kdtree2 (kdtree2_data, arrange);
}
因为那时使用的是树,我定义:
extern "C" void n_nearest_around_point_kdtree2 (int idxin, int correltime, int nn) {
kdtree2_result_vector result;
global_kdtree2->n_nearest_around_point (idxin, correltime, nn, result);
}
kdtree2_result_vector从vector类。这编译没有错误,并且可以链接生成的库,并且可以从C访问C函数。
问题是调用n_nearest_around_point_kdtree2会使程序崩溃。我怀疑设置树并在第二个函数调用中使用它,树以某种方式被释放/销毁。在调用C-测试程序下面贴:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "kdtree2.h"
#define MALLOC_2D(type,x,y) ((type**)malloc_2D_kdtree2((x),(y),sizeof(type)))
void **malloc_2D_kdtree2 (const int x, const int y, const int type_size) {
const int y_type_size = y * type_size;
void** x_idx = (void **) malloc (x * (sizeof (void **) + y_type_size));
if (x_idx == NULL)
return NULL;
char* y_idx = (char *) (x_idx + x);
for (int i = 0; i < x; i++)
x_idx [ i ] = y_idx + i * y_type_size;
return x_idx;
}
int main (void) {
float **data = MALLOC_2D (float, 100, 3);
for (int i = 0; i < 100; i++)
for (int j = 0; j < 3; j++)
data [ i ][ j ] = (float) (3 * i + j);
// this works fine
tnrp (data, 100, 3, false);
new_kdtree2 (data, 100, 3, false);
// this crashes the program
n_nearest_around_point_kdtree2 (9, 3, 6);
delete_kdtree2 ();
free (data);
return 0;
}
至于我可以看到,搜索互联网,它应该工作,但我明显失去了一些东西在勇敢重要(对我来说)新的世界的C++。
编辑:
决议,由于larsmans。我定义下面的类(从早期什么larsmans发布派生):
class kdtree {
private:
float **data;
multi_array_ref<float,2> data_ref;
kdtree2 tree;
public:
kdtree2_result_vector result;
kdtree (float **data, int n, int dim, bool arrange) :
data_ref ((float *) &data [ 0 ][ 0 ], extents [ n ][ dim ], c_storage_order ()),
tree (data_ref, arrange)
{
}
void n_nearest_brute_force (std::vector<float>& qv) {
tree.n_nearest_brute_force (qv, result); }
void n_nearest (std::vector<float>& qv, int nn) {
tree.n_nearest (qv, nn, result); }
void n_nearest_around_point (int idxin, int correltime, int nn) {
tree.n_nearest_around_point (idxin, correltime, nn, result); }
void r_nearest (std::vector<float>& qv, float r2) {
tree.r_nearest (qv, r2, result); }
void r_nearest_around_point (int idxin, int correltime, float r2) {
tree.r_nearest_around_point (idxin, correltime, r2, result); }
int r_count (std::vector<float>& qv, float r2) {
return tree.r_count (qv, r2); }
int r_count_around_point (int idxin, int correltime, float r2) {
return tree.r_count_around_point (idxin, correltime, r2); }
};
的代码从C调用这些函数:
kdtree* global_kdtree2 [ 8 ];
extern "C" void new_kdtree2 (const int thread_id, float **data, const int n, const int dim, bool arrange) {
global_kdtree2 [ thread_id ] = new kdtree (data, n, dim, arrange);
}
extern "C" void delete_kdtree2 (const int thread_id) {
delete global_kdtree2 [ thread_id ];
}
extern "C" void n_nearest_around_point_kdtree2 (const int thread_id, int idxin, int correltime, int nn, struct kdtree2_result **result) {
global_kdtree2 [ thread_id ]->n_nearest_around_point (idxin, correltime, nn);
*result = &(global_kdtree2 [ thread_id ]->result.front ());
}
,并最终在C程序开始使用它的所有:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "kdtree2.h"
int main (void) {
float **data = MALLOC_2D (float, 100, 3);
for (int i = 0; i < 100; i++)
for (int j = 0; j < 3; j++)
data [ i ][ j ] = (float) (3 * i + j);
int thread_id = 0;
new_kdtree2 (thread_id, data, 100, 3, false);
struct kdtree2_result *result;
n_nearest_around_point_kdtree2 (thread_id, 28, 3, 9, &result);
for (int i = 0; i < 9; i++)
printf ("result[%d]= (%d,%f)\n", i , result [ i ].idx, result [ i ].dis);
printf ("\n");
n_nearest_around_point_kdtree2 (thread_id, 9, 3, 6, &result);
for (int i = 0; i < 6; i++)
printf ("result[%d]= (%d,%f)\n", i , result [ i ].idx, result [ i ].dis);
delete_kdtree2 (thread_id);
free (data);
return 0;
}
被引用论文的API文档相当片状,笔者的FTP服务器不响应,所以我不能肯定地说,但我的直觉是,
multi_array_ref<float,2> kdtree2_data((float *)&data[0][0], extents[n][dim],
c_storage_order());
global_kdtree2 = new kdtree2(kdtree2_data, arrange);
构建体中的kdtree2
通过在global_kdtree2
对象存储到kdtree2_data
的引用,而不是使一个完整副本。由于kdtree2_data
是局部变量,因此在new_kdtree2
返回时会被销毁。您必须保持活动状态,直到n_nearest_around_point_kdtree2
完成。
什么是崩溃的堆栈跟踪? – outis 2011-03-06 14:18:36
似乎对我来说......如果你能为每个人提供一个最小的测试用例来重现这个错误,它会更容易帮助你 – Constantin 2011-03-06 14:20:14