Using C++ Library in C Code

Using C Libraries for C++ Programs

Yes, C++ can compile C with a C++ compiler and you can link C++ against C. Just be sure that any C function you call uses C linkage. This is made by enclosing the prototype of the C function by an extern "C"

#ifdef __cplusplus
extern "C"{
#endif

void c_function_prototype();

#ifdef __cplusplus
}
#endif

The headers for the library you are trying to use may already do that.

Use C library in a C++ code with non-compatible code

A straightforward (though perhaps not the only) solution:

Write a thin C++ bindings shim for your C library.

Since your library contains C code which is not C++-compatible - not in the common subset of both languages - you have to write bindings which C++ can use. These will need to be written in C, not in C++.

Let's call the bindings shim files you write frr_cpp_bindings.h and frr_cpp_bindings.c.

The shim's header file, frr_cpp_bindings.h, will expose essentially the same thing as libfrr.h, but without any actual code ( like ./r.inf = &_frrmod_info ) - only function and type definitions which are in the common subset of C++ and C.

The implementation of this shim (frr_cpp_bindings.c) will include libfrr.h directly and basically just forward calls to to libfrr.h-exposed C functions.

Finally, in the frr_cpp_bindings.h file, you can have something like this:

#ifdef __cplusplus
extern "C" {
#endif

// all of the actual C code

#ifdef __cplusplus
}
#endif

and this means you won't need to extern "C" in the C++ code.

Finally, so your C++ source files will have:

#include <frr_cpp_bindings.h>

and will not try to include the incompatible header directly.

Using C++ library in C code

Yes, this is certainly possible. You will need to write an interface layer in C++ that declares functions with extern "C":

extern "C" int foo(char *bar)
{
return realFoo(std::string(bar));
}

Then, you will call foo() from your C module, which will pass the call on to the realFoo() function which is implemented in C++.

If you need to expose a full C++ class with data members and methods, then you may need to do more work than this simple function example.

How to use C libraries in Vlang for basic statistics

Yes, you can call C libraries from V.

You need to make the C library's structs, typedefs and functions known to V by defining them in V first - before calling/using them.

For structs you conveniently only need to define the fields you need to use.

Here's some examples:

  • via 2D game framework wrapping several C libs
  • sokol in vlib
  • v-miniaudio wrapper (disclaimer: my own module)

Generally you can find a lot of C wrapper code in vlib itself. (We're working on replacing C with pure V)

Is it possible to include C++ libraries in C programs?

No, it is not possible. One thing that is certanly going to miss are exception handling functions. You have to compile the main using c++ compiler.

If you really want to develop in c, and use a c++ library, you can develop a c library, and compile main with g++.


Even if compiling succeeds, linking will fail at the end. See :
Why can't I link a mixed C/C++ static library that has a C interface using gcc?

And it is not only exception functionality missing. There are lots of other things, which can be easily solved by using g++ to link everything.

As I said above, the solution is to call some function from main and link it with g++ :

#include "my_c_main.h"

int main(int argc, char* argv[])
{
return run_my_c_main( argc, argv );
}

How to use a C library from D?

It is possible to call C libraries from D. What you need to do is to convert the C header files to D. For the most part this is pretty straightforward, and there is a hard-to-use command-line tool to help automate the process. It's never really worked for me on anything but toy examples, but it could be a good start to see the kind of transformations that need to be done. Just put a snippet you're having trouble translating into a header by itself and see what htod does with it.

The biggest problem you'll usually encounter is creative use of the C preprocessor. Some things can be turned into version() statements in D, but not all.

As for actually compiling and linking with the code, on unix-like platforms I think you can compile and link in the C code using GCC. On Windows you either have to compile the C files using DMC and link with DMD. Or you can compile the C code into a DLL using any compiler capable of that, and then to link with DMD you need to make a DMD-compatible import lib out of the DLL. This can be done using the implib tool found in the free Basic Utilities Package available from DigitalMars.

There are also a lot of these header translations have already been done. It's useful to browse the Bindings project of Dsource first, or ask on the digitalmars D newsgroups first before embarking on something big like translating GTK headers. A lot of popular libraries like GTK have already been wrapped (e.g. here: GTKD)

Include an external library in C

First, as a beginner, you should always ask GCC to compile with all warnings and debugging information enabled, i.e. gcc -Wall -g. But at some time read How to invoke gcc. Use a good source code editor (such as GNU emacs or vim or gedit, etc...) to edit your C source code, but be able to compile your program on the command line (so don't always use a sophisticated IDE hiding important compilation details from you).

Then you are probably missing some Harvard specific library, some options like -L followed by a library directory, then -l glued to the library name. So you might need gcc -Wall -g -lcs50 (replace cs50 by the appropriate name) and you might need some -Lsome-dir

Notice that the order of program arguments to gcc is significant. As a general rule, if a depends upon b you should put a before b; more specifically I suggest

  1. Start with the gcc program name; add the C standard level eg -std=c99 if wanted
  2. Put compiler warning, debugging (or optimizing) options, eg -Wall -g (you may even want to add -Wextra to get even more warnings).
  3. Put the preprocessor's defines and include directory e.g. -DONE=1 and -Imy-include-dir/
  4. Put your C source file hello.c
  5. Put any object files with which you are linking i.e. bar.o
  6. Put the library directories -Lmy-lib-dir/ if relevant
  7. Pur the library names -laa and -lbb (when the libaa.so depends upon libbb.so, in that order)
  8. End with -o your-program-name to give the name of the produced binary. Don't use the default name a.out

Directory giving options -I (for preprocessor includes) and -L for libraries can be given several times, order is significant (search order).

Very quickly you'll want to use build automation tools like GNU make (perhaps with the help of remake on Linux)

Learn also to use the debugger gdb.

Get the habit to always ask for warnings from the compiler, and always improve your program till you get no warnings: the compiler is your friend, it is helping you!

Read also How to debug small programs and the famous SICP (which teaches very important concepts; you might want to use guile on Linux while reading it, see http://norvig.com/21-days.html for more). Be also aware of tools like valgrind

Have fun.

How to use C library from Haskell?

Okay, there are several things to do here:

  • Rename "lib.h" to "lib.c". It's a C source file (containing code), not a C header file.
  • Ideally, add a separate "lib.h" header file with the prototype for getSize.
  • Fix the bug in "lib.c". You want "%lf" in place of "$f" to read in a double.
  • Compile the program with ghc instead of running it with runghc. A single ghc command can compile and link both Haskell modules and C code.

In other words, your files should look like:

// lib.c
#include "lib.h"
#include <stdio.h>
double getSize() {
double size = 0;
scanf("%lf", &size);
return size;
}
// lib.h
double getSize(void);
-- Ffi.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Ffi where
import Foreign
import Foreign.C.Types
foreign import ccall "lib.h getSize" c_size :: IO Double
-- Main.hs
module Main where
import Ffi
main :: IO ()
main = do a <- getLine
b <- c_size
print $ "got from C: " ++ show b

and you should compile it with:

$ ghc Main.hs lib.c
[1 of 2] Compiling Ffi ( Ffi.hs, Ffi.o )
[2 of 2] Compiling Main ( Main.hs, Main.o )
Linking Main ...

Then you can run it, supply a line for the Haskell getLine and a second line for the C scanf, and it should work fine:

$ ./Main
hello world!! -- line for Haskell
135.0 -- line for C
"got from C: 135.0"

How to handle differently sized type in C library from C++

You could write your own header file and use that instead of the broken one that is provided by the library:

fixed_lib.h

typedef struct {
int numValues;
int values[20];
} bArray;

int arraySize();

Of course, this means that you would need to maintain it in case the library is updated. However, if the library is actively maintained, then perhaps a better approach would be to send a pull request to resolve the issue upstream.

Furthermore, if there are other headers in the C library which depend on lib.h, then lib.h should really have a header guard, that must be used in your replacement as well, and you must make take care to include the replacement first.

If there is no header guard, then you would have to duplicate all such headers that you depend on, if those headers also depend on lib.h.

I guess compiling the external library with a C++ compiler instead of a C compiler would work, correct?

It could only potentially work if the library happens to have been written in a subset of C that is also valid C++. Furthermore, this C++ compiled version would not be binary-compatible with the C version of the library, so you then cannot have other dependencies which themselves depend on this (originally) C library.


If modifying the C library is OK, another approach would be to fix the library header itself to use the actual boolean data type:

lib.h

#ifndef __cplusplus
#include <stdbool.h>
#endif

typedef struct {
int numValues;
bool values[20];
} bArray;

int arraySize();

Of course, this would require you to re-compile the library, and it would no longer be binary compatible with the original version that used int. Furthermore, this would make the library require C99 standard, and could no longer work in C89.



Related Topics



Leave a reply



Submit