我开发了一些需要集成到现有C代码中的函数来更新其功能。 为了使新函数尽可能简单,我定义了一个容器结构,其中包含我需要的所有poiners和数据,例如
typedef struct parameters
{
double time;
int num_sp;
int num_nodes;
int dielCount;
double meshbounds[6];
} Params;
typedef struct FGM_Container
{
dev_nodes *d_nodes;
dev_nodes *h_nodes;
dev_species *d_sp;
dp_tree *octree;
dp_params *dp_pars;
dev_params *d_p;
Params p; /* Parameters */
Nodes *n; /* nodes array */
int free_dev_flag;
double guard_range;
int max_octree_depth;
} fgm_container;
我将我的函数编译成一个名为FGM的共享库(.so因为我在Linux中工作),提供了一个包含原型的头文件,以便从原始代码调用函数并成功重建整个项目。但是,当执行进入我的函数时,传递给它们的变量似乎不会保留相同的值。这是一个非常简单的例子,之前和之后的代码更复杂,但这代表了我观察到的行为:
int fgm_init(fgm_container *fgmc, int verbose);
int main()
{
int fgm_ok = 0;
int free_dev_flag;
double guard_range = 0;
int max_octree_depth = 5;
Params p;
fgm_container fgmc;
//Set parameters
p.time = 0;
p.num_sp = 2;
p.num_nodes = 500;
p.dielCount = 1;
p.meshbounds[0] = -0.019;
p.meshbounds[1] = 0.0475;
p.meshbounds[2] = -0.045;
p.meshbounds[3] = 0.032;
p.meshbounds[4] = -0.027;
p.meshbounds[5] = 0.010;
//Fill FGM container
fgmc.p = p;
fgmc.guard_range = guard_range;
fgmc.max_octree_depth = max_octree_depth;
//Print original data
printf("Original data:\n");
printf("dielCount: %d\n", fgmc.p.dielCount);
printf("species: %d\n", fgmc.p.num_sp);
printf("meshb: %lf %lf\n", fgmc.p.meshbounds[0], fgmc.p.meshbounds[1]);
//Initialize FGM library
fgm_ok = fgm_init(&fgmc, 2);
if (fgm_ok != 0)
{
printf("FGM initialization failed. Exiting.\n");
exit(-1);
}
return 0;
}
int fgm_init(fgm_container *fgmc, int verbose)
{
int ok_flag=0;
//Extract data from FGM container
Params p = fgmc->p;
double guard_range = fgmc->guard_range;
int max_octree_depth = fgmc->max_octree_depth;
if (verbose > 0) printf("FGM: Initializing...\n");
printf("species: %d\n", p.num_sp);
printf("meshb: %lf %lf\n", p.meshbounds[0], p.meshbounds[1]);
printf("dielCount: %d\n", p.dielCount);
getchar();
//Proceed with other initialization steps...
return ok_flag;
}
此代码在我的屏幕上输出
Original data:
dielCount: 1
species: 2
meshb: -0.019000 0.047500
FGM: Initializing...
dielCount: 28203712
species: 2
meshb: 0.000000 0.000000
dielcount: 28203712
每次启动代码时,dielCount
值都会更改,就好像它是一个非初始化变量一样。由于各种参数用于各种malloc函数,所以事情很快就会失控,我开始出现内存错误等问题。
此外,如果我尝试通过值将参数结构本身传递给初始化函数,我会得到相同的结果,即:
int fgm_init(fgm_container *fgmc, Params p, int verbose);
int main()
{
// Same steps as before...
//Initialize FGM library
fgm_ok = fgm_init(&fgmc, p, 2);
if (fgm_ok != 0)
{
printf("FGM initialization failed. Exiting.\n");
exit(-1);
}
return 0;
}
int fgm_init(fgm_container *fgmc, Params p, int verbose)
{
int ok_flag=0;
if (verbose > 0) printf("FGM: Initializing...\n");
printf("species: %d\n", p.num_sp);
printf("meshb: %lf %lf\n", p.meshbounds[0], p.meshbounds[1]);
printf("dielCount: %d\n", p.dielCount);
getchar();
//Proceed with other initialization steps...
return ok_flag;
}
我想指出共享库已经过验证,可以在集成到目标项目(相当大)之前通过单独但很小的测试正确执行。
这个错误让我忙了好几个小时,因为我试图解决它,而且显然我缺少了一些东西。 关于使用共享库,我应该知道什么,因为这是我第一次自己创建一个?这可能与编译有关,因为原始项目是用C编译器编译的,我的库是用NVIDIA NVCC编译器编译的(因为我也使用了一些CUDA调用,但它们是在麻烦的部分之后),这是一个C ++编译器,用于编译。主机代码部分? 感谢您提供的任何见解。
答案 0 :(得分:1)
您是否检查过.so文件中的符号(使用nm或类似文件)? C ++编译器可能会破坏名称,从而导致应用程序中发生奇怪的事情。
在结构周围添加extern "C"
可能会解决您的问题。
例如:
extern "C" {
typedef struct parameters
{
double time;
int num_sp;
int num_nodes;
int dielCount;
double meshbounds[6];
} Params;
}