c++ - 从 C 代码调用 C++ 函数时遇到问题

标签 c++ c

我想从 C 代码调用一些 C++ 函数。我的项目中有三个文件:main.ccgal_kernel.cppcgal_kernel.h

当我尝试编译它们时出现编译错误。

这是三个文件。

cgal_kernel.h

typedef enum{
  LEFT_TURN,
  COLLINEAR,
  RIGHT_TURN
} Orientation;

/* Given points p,q,r determine if the link p-q-r is a left turn, right-turn or collinear
*/
extern Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry);  

cgal_kernel.cpp

#include "cgal_kernel.h"

extern "C" Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry)  
{
  return LEFT_TURN ;

}

main.c

#include <stdio.h>
#include "cgal_kernel.h"

int main(void)
{
  double px = 0.0;
  double py = 0.0;

  double qx = 0.0;
  double qy = 1.0;

  double rx = 1.0;
  double ry = 1.0;

  Orientation test= orientation_2 ( px,  py,  qx,  qy,  rx,  ry);

  printf("Answer is %d\n", test);
  return 0;
}

我希望将 cgal_kernel.cpp 编译成一个共享库文件,以供其他语言通过其外部函数接口(interface)使用。

我的编译步骤,存储在 bash 脚本中是

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 
set -ex # Display compilation process.

rm  -f  *~  *.o  *.so
g++ -c -Wall  -Werror -fPIC cgal_kernel.cpp  # Convert to object file
g++ -shared   cgal_kernel.o -o libcgal_kernel.so      
gcc -g -Wall  main.c -o main -I. -L. -lcgal_kernel

运行上述构建脚本后,出现以下编译错误。

+ rm -f *~ *.o *.so
+ g++ -c -Wall -Werror -fPIC cgal_kernel.cpp
In file included from cgal_kernel.cpp:1:0:
cgal_kernel.h: In function ‘Orientation orientation_2(double, double, double, double, double, double)’:
cgal_kernel.h:17:20: error: previous declaration of ‘Orientation orientation_2(double, double, double, double, double, double)’ with ‘C++’ linkage
 extern Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry);  
                    ^
cgal_kernel.cpp:3:103: error: conflicts with new declaration with ‘C’ linkage
 extern "C" Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry)  

我哪里错了?我尝试从函数签名中的 cgal_kernel.cpp 文件中删除 "C",然后出现错误

+ rm -f *~ cgal_kernel.o libcgal_kernel.so
+ g++ -c -Wall -Werror -fPIC cgal_kernel.cpp
+ g++ -shared cgal_kernel.o -o libcgal_kernel.so
+ gcc -g -Wall main.c -o main -I. -L. -lcgal_kernel
/tmp/cclw7kGD.o: In function `main':
/home/gaurish/Dropbox/MyWiki/research_projects/MiCha/main.c:15: undefined reference to `orientation_2'
collect2: error: ld returned 1 exit status

关于如何从 C 代码调用 C++ 函数,我似乎犯了一些基本错误,但我似乎无法弄清楚!


编辑: 如果我将 extern "C" 添加到 cgal_kernel.hcgal_kernel.cpp 文件中的函数签名,我会收到以下错误:

+ rm -f *~ cgal_kernel.o libcgal_kernel.so
+ g++ -c -Wall -Werror -fPIC cgal_kernel.cpp
+ g++ -shared cgal_kernel.o -o libcgal_kernel.so
+ gcc -g -Wall main.c -o main -I. -L. -lcgal_kernel
In file included from main.c:2:0:
cgal_kernel.h:17:8: error: expected identifier or ‘(’ before string constant
 extern "C" Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry);  
        ^
main.c: In function ‘main’:
main.c:15:3: warning: implicit declaration of function ‘orientation_2’ [-Wimplicit-function-declaration]
   Orientation test= orientation_2 ( px,  py,  qx,  qy,  rx,  ry);
   ^

最佳答案

从 C 调用 C++ 代码的最简单方法是编写以下形式的有效 C/C++ 头文件:

// header guard
#ifdef __cplusplus
extern "C" {
// alternatively, you could have separate C and C++ headers and have
// the extern "C" before each function in your C++ header
#endif

// Valid C header

#ifdef __cplusplus
}
#endif

然后继续从 C 中使用它。在 C++ 中,按照您通常的方式定义函数。

以你的例子为例:

cgal_kernel.h

#ifdef __cplusplus
extern "C" {
#endif

typedef enum{
  LEFT_TURN,
  COLLINEAR,
  RIGHT_TURN
} Orientation;

/* Given points p,q,r determine if the link p-q-r is a left turn, right-turn or collinear
*/
Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry);

#ifdef __cplusplus
}
#endif

cgal_kernel.cpp

#include "cgal_kernel.h"

Orientation orientation_2(double px, double py, double qx, double qy, double rx, double ry)  
{
  return LEFT_TURN ;
}

请注意,您的主文件应该是一个 C++ 文件,正如我们可以从 How to mix C and C++ 中读到的那样

关于c++ - 从 C 代码调用 C++ 函数时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43266704/

相关文章:

无法释放 C 中的一些内存

c - 在 arm7 问题 : malloc return NULL 中使用 gcc 实现 malloc

c - execve grep 进程永不退出

c++ - OOM 时不会崩溃的内存泄漏,或出现在 massif/valgrind 中

c++ - 对并行数组中的两组数据进行排序

c - 结构数组上的 free()

c - 如何在不使用数组的情况下找到丢失的数字?

c++ - 无法在派生类函数内部访问基类的 protected 数据成员

c++ - C++ STL 中 hash_map 结构的内存开销

C++ 这个程序中cout是怎么执行的?