Using Eigen in a C Project
Asked Answered
S

1

6

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.

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)

Stebbins answered 12/11, 2014 at 14:17 Comment(12)
possible duplicate of C library for linear algebraPerformative
Eigen is a header only library that uses heavy template meta programming. You are not going to be able to use it in C at all.Greenbelt
You have (at least) two options: a) try to make the project compile with a C++ compiler, which can be anything from trivial to quite complicated or b) isolate the parts which use Eigen in a static/dynamic library and expose them to the C project via a C interface.Wednesday
I prefer to stick to Eigen if possible... Can you give me more details on how to proceed; you can pick the option that you guess is easierStebbins
@ryyker: It's not. This question asks how to use a specific library from C, which is on-topic. A request for a library recommendation, which seems to be your interpretation, is off-topic anyway.Regiment
Do you have the option of changing your project to C++? Why do you want to "code in C"?Regiment
The whole project is written in C and I am only going to modify it by adding a couple of functions... Switching the whole project to C++ is not an option I guessStebbins
Can someone confirm what @Greenbelt said? If that's the case, I can stop spending time on Eigen and look for another library to useStebbins
sjdowling is right that you cannot directly use Eigen in a C-only project. However, you can call functions implemented in C++ from C. So you can have a C++ part which uses Eigen and exposes a C interface, which the C portion of the project uses.Wednesday
@reima: Thanks for the clarification. I think that should be a reasonable way to proceed then. However, I have no previous experience doing something like that. If you can detail, give me an example, or point me to some related link, I would highly appreciate it.Stebbins
@Stebbins I'll create a small example and put it in an answer shortly.Wednesday
@BenVoigt - Agreed, thanks for bringing it up. Are you aware if there is a way to reverse a vote to close?Performative
W
17

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.

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.

Library interface

/* foo.h */

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

void foo(int arg);

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

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.

Library implementation

/* foo.cpp */

#include "foo.h"

#include <iostream>

extern "C" {

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

} /* extern "C" */

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).

C project

/* main.c */

#include "foo.h"

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

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

Building

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

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.

Wednesday answered 12/11, 2014 at 15:36 Comment(3)
Very nice. Generally applicable approach not commonly known.Performative
Very Well Explained! :) I still have 2 questions though regarding that approach: First, is it possible to use C and C++ in the same main.c file (for sure after adding extern "C" for the C++ lines), or splitting them into foo.cpp and main.c as in your example is a must? Second, can someone comment on the computational efficiency of that approach as compared to directly using CLAPACK for example?Stebbins
1. If you compile main.c with a C compiler then no, you cannot use C++ features in there. Using extern "C" will restrict you to C constructs (i.e. no templates, function overloads etc.). 2. This can only be answered by profiling your actual use case. Using a C++ library behind a C interface will add another layer of indirection. If that has a measurable performance impact I cannot say.Wednesday

© 2022 - 2024 — McMap. All rights reserved.