在 C 项目中使用 Eigen

2022-01-25 00:00:00 c include c++ eigen

我正在做一个从 Internet 获得的 C 项目,我正在尝试向项目中添加一些涉及线性代数的函数.在我之前的 C++ 工作中,我通常依赖 Eigen 进行线性代数.

I am working on a C project I got from the Internet, and I'm trying to add some functions to the project that involve linear algebra. In my previous works in C++, I usually rely on Eigen for linear algebra.

有没有办法将 Eigen 用于 C 项目?如果是,我应该怎么做才能使它起作用?(仅仅添加 Eigen 头文件是不够的,例如标准 C++ 文件不会自动包含在内)

Is there a way to use Eigen for a C project? If yes, what should I do to make that work? (Simply adding Eigen header files is not enough since for example the standard C++ files do not get included automatically)

推荐答案

Eigen 是一个库,它大量使用了 C++ 中没有的 C++ 特性.因此,它不能直接从 C 翻译单元中使用.

Eigen is a library which heavily uses C++ features which are not present in C. As such, it cannot be directly used from a C translation unit.

但是,您可以使用 Eigen 将部件包装在单独的共享库中并公开 C 接口.这是一个如何编写这样一个库的小例子.

However, you can wrap the parts using Eigen in a separate shared library and expose a C interface. Here is a small example how one could write such a library.

/* foo.h */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

void foo(int arg);

#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */

默认情况下,C++ 对导出函数的名称使用与 C 不同的修饰规则.我们使用 extern "C" 来指示 C++ 编译器使用 C 规则.因为接口文件将被 C++ 和 C 编译器看到,我们将 extern 声明包装在 #ifdefs 中,这只会为 C++ 编译器触发.

By default, C++ uses different mangling rules than C for names of exported functions. We use extern "C" to instruct the C++ compiler to use the C rules. Because the interface file will be seen by both the C++ and the C compiler, we wrap the extern declaration in #ifdefs which will only trigger for the C++ compiler.

/* foo.cpp */

#include "foo.h"

#include <iostream>

extern "C" {

void foo(int arg) {
  std::cout << arg << std::endl;
}

} /* extern "C" */

我们还需要在接口的定义中定义C联动.除此之外,您可以在实现中使用您喜欢的任何 C++ 功能(包括 Eigen).

We also need to define C linkage in the definition of the interface. Other than that, you can use any C++ features you like in the implementation (including Eigen).

/* main.c */

#include "foo.h"

int main() {
  foo(42);
  return 0;
}

包含接口标头并像使用任何其他 C 库一样使用它.

Include the interface header and use it like any other C library.

$ g++ foo.cpp -shared -fPIC -o libfoo.so
$ gcc main.c -L. -lfoo -o main

使用 C++ 编译器构建共享库 libfoo.so.使用 C 编译器构建主程序,链接到共享库.确切的构建步骤可能因您的编译器/平台而异.

Use a C++ compiler to build the shared library libfoo.so. Use a C compiler to build the main program, linking to the shared library. The exact build steps may vary for your compiler/platform.

相关文章