【发布时间】:2014-11-06 19:06:51
【问题描述】:
我的目的是从我的 C++ 代码中调用一些 C 函数并传递一些 C++ 对象。 事实上,我正在使用 GSL 库中的集成例程(用 C 编写),请参阅此 link,
我的代码sn-p:
// main.cpp
#include <stdio.h>
#include <gsl/gsl_integration.h>
#include <myclass.h>
/* my test function. */
double testfunction ( double x , void *param ) {
myclass *bar=static_cast<myclass*>(param);
/*** do something with x and bar***/
return val;
}
int main ( int argc , char *argv[] ) {
gsl_function F; // defined in GSL: double (* function) (double x, void * params)
/* initialize.*/
gsl_integration_cquad_workspace *ws =
gsl_integration_cquad_workspace_alloc( 200 ) ;
/* Prepare test function. */
myclass foo{}; // call myclass constructor
F.function = &testfunction;
F.params = &foo;
/* Call the routine. */
gsl_integration_cquad( &F, 0.0,1.0,1.0e-10,1.0e-10,ws, &res,&abserr,&neval);
/* Free the workspace. */
gsl_integration_cquad_workspace_free( ws );
return 0;
}
在我的情况下,直接调用 gsl_integration_cquad 似乎没问题,只要标头包含“ifdef __cplusplus”之类的东西,我关心的是 callback F,最初在 C 中定义,我可以通过以这种方式测试函数和 C++ foo 对象? .
或者有没有更好的方法来做这种事情,也许是重载和使用仿函数?
P.S. 我可以在回调函数中进行异常处理吗? (在“testfunction”中使用 try catch)。它适用于我的情况,但不确定它是否合法。
【问题讨论】:
-
你的方式已经足够好了——没有限制让事情变得不必要的复杂。只要您的链接器设法构建最终的可执行文件或共享对象,您就可以以任何方式混合 c 和 c++。
-
简短的回答是肯定的,这很好。但是,我会将
__cdecl添加到testfunction的声明中,以防它不是给定平台上的默认值。 -
@lowtech 谢谢,无论如何,我经常听说混合 c 和 c++ 会导致问题...
-
@JamesKanze NOPE,它是合法的 C++,无需将其设为外部“C”。当您尝试链接 C 对象文件时使用外部“C”以及防止某些函数上的名称修改的方法
-
@lowtech 不符合标准。 §7.5/1:“具有不同语言链接的两个函数类型是不同的类型,即使它们在其他方面是相同的。”如果他正在使用的结构是在
extern "C"块中声明的,那么指向函数的指针就是指向extern "C"函数的指针,并且具有与他的函数不同的类型。 (而且 FWIW,我使用了 C 和 C++ 之间调用约定不同的编译器。)