更新
我发现如果我在构造函数中通过引用传递,那么它就解决了A.cpp中的问题!
即。 InfoPass(vector<double> &arg0, vector<double> &arg1...)
,但原因是什么?
更新
基本上我想从c ++调用一些c代码。
正如c手册中所解释的,为了避免使用gloabal变量,a&#34; void * fdata&#34;用于获取附加信息,如果不是,则指向NULL。
int f(unsigned ndim, unsigned npts, const double *x, void *fdata,
unsigned fdim, double *fval);
现在我需要打包一些c ++对象并传递给&#34; f&#34;通过这个* fdata参数,我能想到的方法是定义一个类&#34; InfoPass&#34;,并将它传递给c例程。
我的c ++代码段(例如A.cpp和B.cpp,当B没问题时,A无法正常工作):
// Example A.cpp
#include "cubature.h" // the c library called cubature
#include "extern_cpp_class.hpp" //
class InfoPass
{
public:
extern_cpp_class obj1;
extern_cpp_class obj2;
extern_cpp_class obj3;
double arr[3];
InfoPass(vector<double>arg0, vector<double>arg1, vector<double>arg2, vector<double>arg3)
: obj1{arg0, arg1}, obj2{arg0, arg2}, obj3{arg0, arg3} {}
};
// the declaration of int f() and cubature() below are in the c code
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval);
int main() {
/*** do something ***/
InfoPass cubpass{arg0, arg1, arg2, arg3}; // initialize
cubature(2, f, &cubpass, 2, xmin, xmax, 1e5, 0, 1e-5, ERROR_PAIRED, OUTPUT, &err);
/*** process with output ***/
}
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval)
{
InfoPass *fcubpass=static_cast<InfoPass*>(fdata);
/*** do things with fcubpass.obj1, .obj2 ... ***/
}
现在,我可以编译(gcc)并运行示例A,奇怪的是,有未完成的行为,有时它会给出NaN,有时会给出非常疯狂的数字......
但是,如果我采用以下方式(例B,使用指向类的指针),那么使用&#34; new&#34;在f,它工作正常!想知道为什么?因为我更喜欢实例A到B,其中我总是需要&#34; new&#34;财产以后...
// Example B.cpp
class InfoPass
{
public:
extern_cpp_class *obj1=NULL;
extern_cpp_class *obj2=NULL;
extern_cpp_class *obj3=NULL;
double arr[3];
~InfoPass(){
delete obj1;
delete obj2;
delete obj3;
}
}
int main() {
/*** do something ***/
InfoPass cubpass; // declare
cubpass.obj1 = new extern_cpp_class(arg0,arg1);
cubpass.obj2 = new extern_cpp_class(arg0,arg2);
cubpass.obj3 = new extern_cpp_class(arg0,arg3);
cubature(2, f, &cubpass, 2, xmin, xmax, 1e5, 0, 1e-5, ERROR_PAIRED, OUTPUT, &err);
/*** process with output ***/
}
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval)
{
InfoPass *fcubpass=static_cast<InfoPass*>(fdata);
/*** do things with fcubpass->obj1, .obj2 ... ***/
}
答案 0 :(得分:2)
由于f
应该是C代码调用的Callback函数,所以它应该使用c的调用约定。
但是由于你在cpp中声明并定义它,它使用另一个调用约定。 所以参数传递可能会出错。
尝试在extern "C"
声明前添加f
。
但这显然不能令人满意地解释,为什么你的一个例子确实有用。
答案 1 :(得分:2)
这里只是在黑暗中拍摄。
extern_cpp_class
个对象的初始化参数是做什么的?如果他们将vector
参数作为参考文件并将其存储起来,那么您将遇到原始A.cpp
的问题,因为参数是在{{1}之后被销毁的临时副本 - 使引用无效构造函数已完成执行。切换到传递引用可以通过确保cubpass
个对象接收extern_cpp_class
中创建的vector
的引用来解决这个问题,这些main
在程序退出之前(可能)保持有效(或至少直到你# 39;重新使用cubpass
)。在B.cpp
中,构造函数已经获得了对vector
的引用,因此没有问题。
答案 2 :(得分:0)
您是否可以更改InfoClass构造函数中的初始化列表以使用括号而不是花括号?
obj1(arg0, arg1), obj2(arg0, arg2), obj3(arg0, arg3)
P.S。我会发布这个评论作为评论,但我还没有声誉。