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.
Related
Stackoverflow won't let me comment because I am a newbie.
Borrowing the title from the question posted here, the accepted solution says that you have to modify the C header file using #ifdef __cplusplus and extern "C".
I have the exact same question but I have been provided a C library containing over 100 .h C header files and .c C program files and now I have to use a C++ library so my main() will be in C++.
So do I now have to add those modifications to each one of those C header files or is there some other approach? My main() is in a .cpp file which will use functions from this C library.
EDIT
This question has been resolved. I wish for this question to be closed or removed.
You don't have to modify any headers. What is necessary is to wrap all C declarations with extern C {}. You can do this just as well in you cpp file:
extern "C" {
#include "some_c_header.h"
}
int main() {
std::cout << "This is C++ code\n";
}
It might be useful to create a header file which simply includes C headers with C linkage:
// c_header.hpp
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "c_header_1.h"
#include "c_header_2.h"
#ifdef __cplusplus
}
#endif
// main.cpp
#include "c_header.hpp" // extern "C" {} already handled for you
Only those declarations of C functions and objects that are accessed by C++ components need to declared with C linkage, and only to the C++ components. Presumably, your new C++ library accesses very little, if anything, from the existing C code, so the primary concern would be whatever is accessed (directly) by main(). Those functions must be declared (to main) with C linkage. If that turns out to be a significant number of things then you could consider refactoring to make it fewer.
Moreover, no, you do not need to modify existing header files. The C++ files that reference your C library, and that therefore include some of its headers, can wrap the relevant #include statements an an extern "C" block to take care of the issue.
i'm using C++ Audio processing library for my Swift project from https://www.surina.net/soundtouch/sourcecode.html
I have also included those cpp file in my compile sources in Projects-targets-build phases.
When i try to import all of library header file in my bridging header
#import "SoundTouch.h"
i got error when try to compile it
Unknown type of name 'namespace' in STTypes.h
'stdexcept' file not found
i'm using namespace in my header file
namespace soundtouch { ... }
i cannot use several standard library also like string
#include <stdexcept>
#include <string>
what i'm missing here?
Swift does not understand C++ even in header files. C does not have namespaces, so when the Swift compiler comes across the word namespace it's going to think the same as the C compiler would, which is that it is the name of a variable. That's not all though. Swift also won't understand other C++ keywords like class nor will it understand C++ style name mangling, even though it does its own name mangling, nor export "C" { ... }.
If you have a C++ header file that you want to import into Swift, you have to make sure all the C++ stuff is hidden with #ifdef __cplusplus just like if you are including the header in a C program. Also, all the function declarations will need to be extern "C" to disable name mangling.
You will need an alternate declaration for classes, you can use void* or I found an incomplete struct type works quite well and you'll need to create C wrapper functions to call functions defined in the class. Something like the following might work (I haven't tested it).
#if defined __cplusplus
extern "C" {
#endif
#if defiend __cplusplus
class Foo
{
void bar(int c);
}
#endif
struct FooHandle;
void Foo_bar(struct FooHandle* foo, int c);
#if defined __cplusplus
}
#endif
And you'll need to define the shim function in a C++ file
#include MyHeader.h
void Foo_bar(struct FooHandle* foo, int c)
{
((Foo*) foo)->bar(c);
}
Apologies if I got the C++ wrong, I haven't used it seriously since 1998
I have a library written by a not very meticulous coder, which includes the following code in a C header file:
/* SomeCHeaderFile.h */
...
#define local static
#define package
#define global
When this file is included in a C++ header, for example:
EDIT: I forgot to mention that I include the header like so:
// SomeCPlusplusSourceFile.cpp
extern "C" {
#include "SomeCHeaderFile.h"
}
...
the compiler gives the following error:
error: constructor cannot be static member function
error: 'std::locale::locale(const std::locale&)' cannot be overloaded
error: with 'std::locale::locale(const std::locale&)'
I only say the coder was not meticulous because she/he never tested it in a C++ code. But I don't know the reasoning behind this to why is this causing the build to fail?
gcc version 4.4.3 | ubuntu linux
It seems the troublesome C header file is redefining tokens in use by the standard C++ header files. If you want to use the C header file in your C++ code, you may be required to include it after the standard header files to prevent this kind of problem.
This may not sufficiently guard you from problems if the C++ code defines its own macros that also redefine the same tokens. If that happens, you will have to segregate your C++ code with files dedicated to C++ that uses the troublesome C header file and C++ code that does not. The C++ code that does use the troublesome C header file makes sure to not use any C++ header file that would cause problems.
You can use C header files in CPP files as follows:
extern "C" {
//Headers go here
}
More details here:
In C++ source, what is the effect of extern "C"?
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.
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.