5

I want to implement a project in C, but it is comfortable to code some part of project in C++ and then call them from main C code.
Is it possible?! if yes, how I can do it?!
thanks in advance :)

P.S.
I used some libraries in my C++ Code such as OpenCV.

Soheil
  • 473
  • 9
  • 23

4 Answers4

4

You'll need to "wrap" your C++ interface with regular C functions that take a parameter to indicate what object they'll be called on. For instance, if you have in C++

class A
{
    // .. boilerplate stuff...
    int SomeMethod(int n, float f);
};

Then along with it, you could declare a function such as

extern "C" int A_SomeMethod(void* Obj, int n, float f)
{
    return(((A*)Obj)->SomeMethod(n, f));
}

If you're not comfortable with the casting of the void*, you can implement some kind of map from an opaque handle to an A*. But the gist is you'll need to keep around some handle/pointer to the object that the method will be called on. In order to get the pointer/handle you'll need to wrap the allocation to:

extern "C" void* A_Instantiate()
{
    return new A;
}

The C++ files should be compiled separately along with the file with the functions above. A separate include for the C compilation should include declarations of all the functions above.

EDIT: The caveats and comments below are important; to answer the question, "Yes it is possible to call C++ from C", and this is one approach. It's not a complete approach as there isn't really a mechanistic way to do it, but it's a start. Also, don't forget to create another call-through for delete, etc, etc.

  • Thanks wilsonmichaelpatrick, but what about using *Compiled* C++ code in my C program?! – Soheil Mar 16 '13 at 18:48
  • What is `A` which used when casting `Obj`?! Is it a predefined type or struct?! – Soheil Mar 16 '13 at 18:54
  • `A` is the C++ class type. Even with compiled C++ code, this approach should work. All you need to do is define the extern "C" methods along the lines I described above, and use those to call through to your C++ code. The C++ code itself does not ned to be changed. –  Mar 16 '13 at 19:26
  • Also, regarding @vonbrand mentioning "Unless strictly required, this is only for dyied-in-the-wool masochists" - he does have a point. Ultimately your project will have to be linked together with a linker that handles C++; so what you'll have will be a bit of a Frankenstein C++ project with C parts that call through to C++ code within it. Summary: you also have to get the build correct. –  Mar 16 '13 at 19:30
  • CAVEAT: there are basically two issues: 1) C++ "name mangling" (the name the C++ linker uses), and 2) the C++ "this parameter" (in class methods). This answer addresses the latter. Another, better solution is to use standalone functions (instead of method parameters) whenever possible. – paulsm4 Mar 16 '13 at 19:34
  • @paulsm4, if it is to interface to an existing C++ blob, OP will have to write a fair amount of glue (`extern "C" {type somefunc(type param) {return somefunc_cxx(param);}}` all over the place, seasoned with contortions to use objects and pass them around), will have to be extra careful to maintain C and C++ data separate, and so on. The name mangling is the least worry (thankfully it won't link if you call the wrong language version of the function). – vonbrand Mar 16 '13 at 22:32
0

yes, you need to specify it as

extern "C"

this way it will make the function to have "C" linkage, then C code can call your function just as if it was in C. This function name will not be mangled then because C doesn't support overloading.

here let me cite @Faisal Vali:

  • extern "C" is a linkage-specification
  • Every compiler is required to provide "C" linkage
  • a linkage specification shall occur only in namespace scope
  • all function types, function names and variable names have a language linkage
  • two function types with distinct language linkages are distinct types even if otherwise identical
  • linkage specs nest, inner one determines the final linkage
  • extern "C" is ignored for class members
  • at most one function with a particular name can have "C" linkage (regardless of namespace)
  • extern "C" forces a function to have external linkage (cannot make it static)
  • Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages is implementation-defined and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved

see Faisal Vali answer here

Community
  • 1
  • 1
4pie0
  • 29,204
  • 9
  • 82
  • 118
  • This will work only for C-compatible functions (_one_ version of overloaded functions, if overloading in this is even handled at all; no references; definitely not member functions, neither for classes nor objects; can use objects and classes internally _only_ and with lots of restrictions). This isn't the intent of the standard, it is to be able to call into C from C++, not the other way around; so it might even be disallowed by your C++/C toolchain. – vonbrand Mar 16 '13 at 22:39
0

Q: Can I access my C code from C++ or vice versa?

A: Yes.

1) The main thing is to use extern "C" { ...} in all your headers to denote C-only functions and data, like this:

http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

/* Header file foo.h */
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif

/* These functions get C linkage */
void foo();

struct bar { /* ... */ };

#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
}
#endif

2) The usual scenario is a C++ main program that calls a mix of C and C++ functions and structs. The structs and functions are all declared in headers, and all have "#ifdef __cplusplus/extern C".

3) Here is a good FAQ on mixing C and C++:

http://www.parashift.com/c++-faq/mixing-c-and-cpp.html

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • 2
    From what I read: this is a project in C, which is trying to call some C++ code, and you are answering as if it was a C++ program calling C functions. – qdii Mar 16 '13 at 18:35
0

Unless strictly required, this is only for dyied-in-the-wool masochists. Doing it will require extreme care on both sides, and could well work today and explode spectacularly with the next compiler update. C++ requires a lot of runtime help, and getting that to work reliably from C isn't normally supported. You can call into C from C++, that is officially supported (and part of the standard, extern "C" and such).

Probably the best bet is to write your C in the subset handled by C and C++ (a starting point on the subtle differences is this) and compile with the C++ compiler. Or get over it and decide what language you like most.

vonbrand
  • 11,412
  • 8
  • 32
  • 52
  • thanks, what about using compiled C++ code in my C program?! P.S: It is *Strictly Required!* :s – Soheil Mar 16 '13 at 19:28
  • Compile with a C++ compiler. Anything else is madness. The reason not to use C++ is either some language related issue (programmer doesn't know the language, against policy, is considered too inefficient, whatever) or due to the runtime requirements. The first ones can be solved and use C++ uniformly; the second costs you will pay with a chimaera anyway, apart from extra problems due to the language mixture. – vonbrand Mar 16 '13 at 21:37