I want to write a C code, say "test.c", and call some C++ functions from it.
I have a header file header.h which has functions defined in it
and a C++ file which has definitions of the functions.
I'm unable to figure out compilation commands and how to use the extern command.
Can someone clarify this?
I want to write a C code, say "test.c" call some C++ functions from it.
Try something like this in your header:
#ifdef __cplusplus
extern "C"
{
#endif
void foo (void);
#ifdef __cplusplus
};
#endif
Then implement foo() in your .cpp file. Make sure that your .cpp file also includes the header.
Related
I am trying to use a C++ header file in my project but it is giving a syntax error. I have tried to convert the project to a C++ project but the error still persists. I don't know exactly and very much confused on how to use extern C command and #ifdef. My C++ header file goes like this:
#pragma once
#define _USE_MATH_DEFINES
#include <complex.h>
#include <math.h>
template <class NumberFormat, size_t DFT_Length>
class SlidingDFT
{
private:
///////////////rest of the code goes here/////
Now if i include this file in my Main.c file and instantiate an object it gives an error: syntax error
Any help will be highly appreciated! Thanx in advance.
The issue is that you have C++ code (template class) in a header file that is being included in a C file. The C compiler doesn't know how to deal with that.
You can and should wrap your C++ code like this:
#ifdef __cplusplus
template <class NumberFormat, size_t DFT_Length>
class SlidingDFT
{
private:
///////////////rest of the code goes here/////
.
.
.
#endif
That will keep you C++ code from being seen by the C compiler.
The other issue you mentioned is extern "C" linkage for functions and when to use it. When you have functions that need to be called from plain C code, they will need to have C linkage. Here are some things to know.
Functions defined in a .c module will have C linkage.
Functions defined in a .cpp module by default will have C++ linkage and will not be able to be called (easily) by C code.
You need to define any functions in a C++ module that you intend to call from C with C linkage. There are required steps in both the .cpp and .h files.
C linkage in .cpp/.h files:
In the .cpp file, define your functions like this:
extern "C" void myfunc()
{
//code
}
Then in the .h file do this:
#ifdef _cplusplus
extern "C" {
#endif
void myfunc();
#ifdef _cplusplus
}
#endif
Now your .h file can be included in both .c and .cpp modules AND the function myfunc() can be called in both as well.
Why shouldn’t extern "C" be specified for a function that needs to be defined as a C function? What effect would that have on the compiler when compiling the file as a C source?
If there is no effect on the C compiler, can’t we just define a function in a header file as below by removing the #ifdef __cplusplus check?
extern "C" {
int MyFunc();
}
An answer to another question says that the #ifdef is needed, but I don’t understand why:
Regarding #2: __cplusplus will be defined for any compilation unit that is being run through the C++ compiler. Generally, that means .cpp files and any files being included by that .cpp file. The same .h (or .hh or .hpp or what-have-you) could be interpreted as C or C++ at different times, if different compilation units include them. If you want the prototypes in the .h file to refer to C symbol names, then they must have extern "C" when being interpreted as C++, and they should not have extern "C" when being interpreted as C -- hence the #ifdef __cplusplus checking.
The construct extern "C" is a C++ construct and is not recognized by a C compiler. Typically, it will issue a syntax error message.
A common trick is to define a macro, for example EXTERN_C, that would expand to different thing depending on if you compile using C or C++. For example:
In a common header file:
#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif
In other files:
EXTERN_C
int MyFunc(void);
EXTERN_C_END
If you compile a source file as C, it will not recognize extern "C", and would usually result in a compilation error.
If you compile a source file as C++, it will recognize extern "C", and the correct names will be linked.
Therefore, you can only use it reliably to specify C symbol names for files you compile as C++.
If you compile sources as C and C++, or your interfaces are intended for C and C++ clients, you would need to specify this one way or another in order for your clients to get the correct symbols when linking (and so on).
Related: You are allowed to write extern "C++" - for C++ translations.
This question already has answers here:
Combining C++ and C - how does #ifdef __cplusplus work?
(4 answers)
Closed 8 years ago.
I'm having a problem with eclipse CDT.
Where i am having a C++ project that uses the C FatFs library. I'm trying to implement the fatfs files.
Question: In multiple files i'm adding
#ifdef __cplusplus
extern "C"
{
#endif
// code..
#ifdef __cplusplus
}
#endif
wrapper. But for some reason, in the one .h file _cplusplus is defined, and in the other .h file the __cplusplus is not defined.
Any suggestions?
Can send screenshot for clarification.
Whether __cplusplus is defined or not depends on how the file that includes the header is being compiled. If the file is being compiled as C source (.c) it will not be defined. if the file is being compiled as C++ source (.cpp, .cc, or any other extension associated as a C++ source file) then __cplusplus will be defined.
Double check the file extensions and if necessary the settings in your project to ensure that the files are being compiled correctly.
Look here: Combining C++ and C — how does #ifdef __cplusplus work?
extern "C" doesn't really change the way that the compiler reads the
code. If your code is in a .c file, it will be compiled as C, if it is
in a .cpp file, it will be compiled as C++ (unless you do something
strange to your configuration).
What extern "C" does is affect linkage. C++ functions, when compiled,
have their names mangled -- this is what makes overloading possible.
The function name gets modified based on the types and number of
parameters, so that two functions with the same name will have
different symbol names.
Code inside an extern "C" is still C++ code. There are limitations on
what you can do in an extern "C" block, but they're all about linkage.
Also, you probably want two #ifdef __cpluspluss:
#ifdef __cplusplus
extern "C" {
#endif
// ...
#ifdef __cplusplus
}
#endif
Otherwise, your C code will never see your definitions.
Why shouldn’t extern "C" be specified for a function that needs to be defined as a C function? What effect would that have on the compiler when compiling the file as a C source?
If there is no effect on the C compiler, can’t we just define a function in a header file as below by removing the #ifdef __cplusplus check?
extern "C" {
int MyFunc();
}
An answer to another question says that the #ifdef is needed, but I don’t understand why:
Regarding #2: __cplusplus will be defined for any compilation unit that is being run through the C++ compiler. Generally, that means .cpp files and any files being included by that .cpp file. The same .h (or .hh or .hpp or what-have-you) could be interpreted as C or C++ at different times, if different compilation units include them. If you want the prototypes in the .h file to refer to C symbol names, then they must have extern "C" when being interpreted as C++, and they should not have extern "C" when being interpreted as C -- hence the #ifdef __cplusplus checking.
The construct extern "C" is a C++ construct and is not recognized by a C compiler. Typically, it will issue a syntax error message.
A common trick is to define a macro, for example EXTERN_C, that would expand to different thing depending on if you compile using C or C++. For example:
In a common header file:
#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif
In other files:
EXTERN_C
int MyFunc(void);
EXTERN_C_END
If you compile a source file as C, it will not recognize extern "C", and would usually result in a compilation error.
If you compile a source file as C++, it will recognize extern "C", and the correct names will be linked.
Therefore, you can only use it reliably to specify C symbol names for files you compile as C++.
If you compile sources as C and C++, or your interfaces are intended for C and C++ clients, you would need to specify this one way or another in order for your clients to get the correct symbols when linking (and so on).
Related: You are allowed to write extern "C++" - for C++ translations.
I'm including a C file called "AniUtils.h" in an Objective C++ class. I understand that I need to use 'extern "C"' if I'm going to include a C file in a C++ file. What's confusing me is that wrapping the include directive in an extern C doesn't seem to work, while putting extern C in the body of the file does.
So, wrapping the include directive doesn't work.
extern "C" {
#include "AniUtils.h"
}
However, doing it this way works fine:
// AniUtils.h
#ifdef __cplusplus
extern "C" {
#endif
// body of included file
#ifdef __cplusplus
}
#endif
Why does the second approach work but not the first?
If your AniUtils.h file is included by any other Objective-C classes (e.g., .m files; not Objective-C++, .mm files), then the first way you've implemented the extern C statement will cause errors.
For example, here is a plain Objective C class that will be importing the problematic AniUtils.h Objective-C++ class. Note that because these files are WowClass.h & WowClass.m, these files will be processed as plain Objective-C:
WowClass.h:
#import <Foundation/Foundation.h>
#import "AniUtils.h"
#interface WowClass : NSObject {
}
#end
WowClass.m:
#import "WowClass.h"
#implementation
.....
#end
Now, if your AniUtils.h is defined in the first manner, you'll get errors when trying to process the WowClass.m file, which includes the extern C statement, as plain Objective-C. Instead, you need to conditionalize the extern C statement in AniUtils.h:
// AniUtils.h
#ifdef __cplusplus
extern "C" {
#endif
// body of included file
#ifdef __cplusplus
}
#endif
Of course, an alternative would be to simply rename WowClass.m to WowClass.mm so that the WowClass interface and implementation files are always processed as Objective-C++, but that kind of misses the point.
Hm, it should work. Are you sure that AniUtils.h is compiled wit a C compiler and not with a C++ one?
There is a really detailed descrption of the whole problematic, take a look here, perhaps it will help you.
http://de.w3support.net/index.php?db=so&id=67894
Are you including AniUtils.h in the .cpp file as well? In the second case it will see the extern "C" as well, but not in the first case.
You might have AniUtils.h included in another file as well.