5

I have a C++ function defined in a .h file as follows and implemented in a .cpp file:

extern "C" void func(bool first, float min, float* state[6], float* err[6][6])
{
    //uses vectors and classes and other C++ constructs
}

How can I call func in a C file? How do I set up my file architecture / makefile to compile this?

Thanks!

3
  • 1
    Is the function defined in the header (i.e., including the part between { }), or is it declared in the header (i.e., ending with );)? If it's the former, you need to write another header file that omits the extern "C" and { } part, and use that for the C part of your program. Commented Jul 20, 2012 at 14:14
  • I do not think I explained my question clearly enough. I will try with better examples. Commented Jul 20, 2012 at 14:21
  • I am going to delete and repost Commented Jul 20, 2012 at 14:22

4 Answers 4

11

You call the function from C in the normal way. However, you need to wrap the extern "C" in an preprocessor macro to prevent the C compiler from seeing it:

#ifndef __cplusplus
extern "C"
#endif
void func(bool first, float min, float* state[6], float* err[6][6]);

Assuming you're working with GCC, then compile the C code with gcc, compile the C++ code with g++, and then link with g++.

Sign up to request clarification or add additional context in comments.

7 Comments

I am getting erros from gcc saying cannot include vector since my C file is including the file where func is defined which uses vectors
You might just want to compile the whole thing with g++? I've typically seen extern "C" in C++ code when you are building a .dll and want to link to it without having to know the mangled name.
@CodeKingPlusPlus: "What do you mean link?" - I fear we have a problem here... check out the -c option in the GCC manuals, and what "linking" is about. Otherwise, no answer you could get here will make sense.
@JoshPetitt: In this case, any kind of shared library (.so, .dll, etc.). Because this is GCC, I think that it is probably Linux, and if it isen't, GCC on other platforms still uses .so. (Mac uses it anyway, on Windows you need a Cygwin-like layer).
Shouldn't the answer be ifdef __cplusplus?
|
4

To call it in C, all you need to do is call it normally. Because you told the compiler to use the C calling conventions and ABI with extern "C", you can call it normally:

func(args);

To compiler, use this for the C++:

g++ -c -o myfunc.o myfunc.cpp

Then this for the C:

gcc -c -o main.o somec.c

Than link:

g++ -o main main.o myfunc.o

Make sure that the C++ header for the function uses ONLY C CONSTRUCTS. So include things like <vector> in the .cpp file instead.

3 Comments

@CodeKingPlusPlus: The -c option tells the compiler to only compile your code to intermediate object code files (.o) which can then be linked together into an executable by excluding the -c option. Object files allow you to combine C and C++, and impose some separation into different parts of the project. They also allow you to compile only small parts of your code, which is crucial to large projects and systems like make.
Thanks! When I run the last compile line (gcc -o main main.o myfunc.o) it fails and tells me I have an undefined reference to files I included in myfunc.cpp
@CodeKingPlusPlus: To what files? What is the exact message?
3

call it in C using

func(/* put arguments here */);

By saying extern "C" you are asking the compiler not to mangle your names. Otherwise, C++ compiler would tend to mangle them (i.e. add additional symbols to make them unique) before the linker.

You'll also want to make sure you have setup to use C calling convention.

3 Comments

Being horribly picky, it disables c++ mangling, not all mangling (c uses mangling in some cases). blogs.msdn.com/b/oldnewthing/archive/2012/05/25/10310148.aspx
@BoBTFish :-) yeah that's why I said "asking" the compiler. +1 for the clarification and hyperlink.
Being horribly picky, it disables c++ mangling, not all mangling (c uses mangling in some cases). devblogs.microsoft.com/oldnewthing/20120525-00/?p=7533
1
//header file included from both C and C++ files

#ifndef __cplusplus
#include <stdbool.h> // for C99 type bool
#endif

#ifdef __cplusplus
extern "C" {
#endif

void func(bool first, float min, float* state[6], float* err[6][6]);

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

// cpp file
#include "the_above_header.h"
#include <vector>

extern "C" void func(bool first, float min, float* state[6], float* err[6][6]);
{
    //uses vectors and classes and other C++ constructs
}

// c file
#include "the_above_header.h"

int main() {
    bool b;
    float f;
    float *s[6];
    float *err[6][6];
    func(b,f,s,err);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.