Reputation:
Suppose you have a .cpp file (that is, compiled using a C++ compiler like MSVC). In that file, you define a struct
in the following way:
struct Pixel
{
float x, y;
};
In the same file, you have a line of code that will call a C function, that requires a C struct
equal to Pixel
. If you write:
Pixel my_pixel
// set my_pixel to something
c_func(&my_pixel);
will it work? I mean, the C++ compiler will create the object my_pixel
, but it will pass it to a function that is compiled as C code (i have only a .lib of that library).
Upvotes: 4
Views: 404
Reputation: 2278
The reason David Schzwartz says you need an extern "C"
block is that without the extern "C" block, the compiler will "mangle" the name of the C function you are calling at the point you call it. If you are calling a C function and not a C++ function, the function's definition in your library will not have a mangled name, so your executable will fail to link.
That's what you want if the function you are calling is written in C++, as name mangling allows for function name overloading. The types of each of a function's parameters are compactly encoded in the mangled function name.
Name mangling was originally provided in C++ to allow C++ object files to be linked with legacy linkers, rather than having to provide a C++-specialized linker that has explicit support for overloaded functions.
C doesn't permit function name overloading, so C function names are never mangled. To provide a prototype in C++ for a single C function you do this:
extern "C" Foo( int theInt );
If you have a whole header file full of C function prototypes and you want to #include that header from a C++ source, enclose the #include in an extern C block
extern "C" {
#include "Foo.h"
}
Upvotes: 1
Reputation: 182885
If the header file is correct, it will work, assuming the C compiler and the C++ compiler use compatible calling conventions. Make sure the header file has an appropriate extern "C"
block that contains the function definition.
Upvotes: 5