I just begin new project in eclipse. Try to use C-library from C++ file.
In headers, where are prototypes of functions, here is:
#ifdef __cplusplus
extern "C" {
#endif
// prototypes...
void Init_Configuration(void);
#ifdef __cplusplus
}
#endif
It's initialize.h. In main.cpp i include this file and try use function:
#include "initialize.h"
int main()
{
Init_Configuration();
// Life cycle
while (1)
{
}
}
After compilation i get this error:
initialize.c:54: undefined reference to `SPI_Cmd'
In source C file "initialize.c", where i also include "initialize.h" i use function from C-library for stm32f2xx:
#include "initialize.h"
#include "stm32f2xx_rcc.h"
#include "stm32f2xx_spi.h"
#include "stm32f2xx_gpio.h"
// some code
SPI_Cmd(SPI1, DISABLE);
// some code
In this library also is this code:
#ifdef __cplusplus
extern "C" {
#endif
...
I don't know where a problem. Please, help!
Related
I am very new to C++ and I'm trying to do my best to have a good project structure from the beginning.
I am using the C library libjpeg and was including it in my .cpp with the use of
extern "C" {
#include <jpeglib.h>
}
It worked fine until I removed it to put it in a header file which now gives me the following errors:
inc/jpeg_utils.h: 6: inc/jpeg_utils.h: extern: not found
inc/jpeg_utils.h: 8: inc/jpeg_utils.h: Syntax error: "}" unexpected
My headerjpeg_utils.h :
#ifndef JPEG_UTILS_INCLUDE
#define JPEG_UTILS_INCLUDE
#include <stdio.h>
extern "C" {
#include <jpeglib.h>
}
int read_jpeg_file(char *filename, int decompression);
void write_jpeg_file(char *filename, unsigned char *image_buffer, int image_width, int image_height, int quality);
#endif
And at the top of jpeg_utils.cpp :
#include "../inc/jpeg_utils.h"
Did I misunderstand the use of a header ?
If you include jpeg_utils.h in a C file, that extern "C" directive will not compile (obviously, C is not C++).
Add a pre-processor directive to extern "C" only when in fact you compile as C++.
#ifdef __cplusplus
extern "C" {
#endif
#include <jpeglib.h>
#ifdef __cplusplus
}
#endif
In my Eclipse C/C++ project there is this undefined reference error which doesn't go away, doesn't matter what I do. I already changed the link order, checked if all files are compiled and included, basically everything, which is recommended in the in the Internet, when facing this problem.
Here's my program:
[...] - means that there is more code, which doesn't relate.
menulib.h
[...]
void start_GUI( void );
[...]
start_GUI.c - Note this is a .c-File
#include "menulib.h"
void start_GUI( void )
{
[...]
}
coreInterface.h
#ifndef COREINTERFACE_H_
#define COREINTERFACE_H_
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
/** only include the Core when compiled for C++ */
#include "Core.h"
#endif /* #ifdef CORE */
#ifdef __cplusplus
extern "C" {
#endif
void init_GUI( Core* core);
#ifdef __cplusplus
}
#endif
#endif /* COREINTERFACE_H_ */
coreInterface.cpp - Note this is a .cpp-File
#include "coreInterface.h"
#include "menulib.h"
void init_GUI( Core* core)
{
gui_core = core;
start_GUI(); // <--- **error appears here** - calls a .c file
}
Here's the error in the makefile (the auto generated one from Eclipse):
g++ -L/home/PC/the_Project/menu_GUI -o "the_Project" [...] ./menu_GUI/coreInterface.o [...] ./menu_GUI/start_GUI.o [...] -lcurses
./menu_GUI/coreInterface.o: In function `init_GUI':
/home/PC/the_Project/Default/../menu_GUI/coreInterface.cpp:23: undefined reference to `start_GUI()'
I believe this is coming from merging the .c and .cpp files. Still I couldn't solve it. Has anyone an idea?
Kind Regards
The problem is that you share the menulib.h header between C and C++ without specifying to C++ compiler that the function start_GUI is defined in C. Use extern "C" in #ifdef not only for init_GUI, but also for start_GUI.
Working example:
#include "coreInterface.h"
extern "C" {
#include "menulib.h"
}
void init_GUI( Core* core)
{
gui_core = core;
start_GUI();
}
I have a static library of functions written in C. Let's say the header file is called myHeader.h and looks like:
#ifndef MYHEADER_H
#define MYHEADER_H
void function1();
void function2();
#endif
function1 and function2 aren't anything too special. Let's say they exist in a file called impl1.c which looks like:
#include "myHeader.h"
void function1() {
// code
}
void function2() {
// more code
}
All of the code mentioned so far is compiled into some static library called libMyLib.a. I'd rather not modify any of the code used to build this library. I also have a C++ header (cppHeader.h) that looks like:
#ifndef CPPHEADER_H
#define CPPHEADER_H
class CppClass {
private:
double attr1;
public:
void function3();
};
#endif
Then cppHeader.cpp looks like:
#include "cppHeader.h"
#include "myHeader.h"
// constructor
CppClass::CppClass(){}
void CppClass::function3() {
function1();
}
When I try to compile this, I get an error about an undefined reference to function1(). I believe that I've linked everything properly when compiling. I'm pretty rusty in my C++. I'm sure that I'm just doing something stupid. I hope that my simple example code illustrates the problem well enough.
Thanks in advance for any help!
The other solution (to the one suggested originally by Yann) is to surround your "C" header with:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
Which saves you from having to remember to do:
extern "C" {
#include "foo.h"
}
every place you use foo.h
Make sure to use:
extern "C" {
#include "myHeader.h"
}
Or else the C++ compiler will generate symbol names which are name-mangled.
I need to call a C++ member function from a C program.
I created .cpp/.h wrapper files in the C code, wrapping the C++ member functions.
i.e.- wrapper.cpp
#include "wrapper.h"
extern "C" {
void wrap_member1()
{
Class::member1();
}
void wrap_member2()
{
Class::member2();
}
}
and wrapper.h:
#include <windows.h>
#include <stdio.h>
#include "../C++ class with members I need to call.h"
extern "C" void wrap_member1();
extern "C" void wrap_member2();
My problem is when I complie:
error C2061: syntax error : identifier 'Class'
It points to the .h declaration of the C++ class as an error. Same result as if I did not have the wrapper files....?
P.S. I also removed the "extern "C" " from the prototypes and received an error on the wrapper function:
error C2732: linkage specification contradicts earlier specification for 'wrap_member1'
Any advice?
There are two issues:
One, you are including a C++ header file in a C header file. This means the C compiler gets C++ code. This is what causes the error you are experiencing. As Reed Copsey suggests, put the #include in the C++ source file instead of the C header file.
Two, you are using extern "C" in the C header file. Wrap your statement in an #ifdef as such:
#ifdef __cplusplus
extern "C" {
#endif
/* Functions to export to C namespace */
#ifdef __cplusplus
}
#endif
This will allow the file to be usable for both C and C++.
In your wrapper you must conditionaly compile the extern "C" part, because is a C++ only construct:
wrapper.h:
#ifdef __cplusplus
extern "C" {
#endif
extern void wrap_member1();
#ifdef __cplusplus
}
#endif
In the wrapper.cpp:
extern "C" void wrap_member1()
{
Class::Member1();
}
In your C module you include only wrapper.h and link to wrapper.obj.
BTW Objective-C is capable of consuming C++, just change the name of your file from *.m to *.mm in XCode.
You need to include your class in wrapper.cpp:
#include "wrapper.h"
#include "ClassHeaderFile.h" // The header that defines "Class"
extern "C" {
void wrap_member1()
{
Class::member1();
}
void wrap_member2()
{
Class::member2();
}
}
I am writing a (my first) C++ class on top of some code written in C, but I can only get the C++ to compile by declaring the C functions in a extern block. My project uses autotools; is there any way to automate this process so I don't have to maintain two header files?
Use a extern block inside a #ifdef in C codes header files
Start of header files
#ifdef __cplusplus
extern "C" {
#endif
...and at end of the header files
#ifdef __cplusplus
}
#endif
This way it will work for being included in both C and C++ sources
Yes create wrapper header files which include your C header files like so...
//Wrapper.h
#ifdef __cplusplus
extern "C"
{
#include "Actual.h"
}
#else
#include "Actual.h"
#endif
//Use.cpp
#include "Wrapper.h"
int main()
{
return 0;
}
//Use.c
#include "Wrapper.h"
/*or #include "Actual.h" */
int main()
{
return 0;
}
Use the C Preprocessor. Do something like this:
#ifdef __cplusplus
extern "C" {
#endif
// code goes here
#ifdef __cplusplus
}
#endif
We have a macro in a header file:
#ifdef __cplusplus
#define _crtn "C"
#else
#define _crtn
#endif
Then in header files, we can use _crtn:
#include "croutine.h"
extern _crtn void MyFunction( ... );
The only gotcha is to make sure you include the header file containing the prototype of MyFunction inside the file containing the implementation of MyFunction so that it is compiled with "C" linkage.
This is the same as #epatel's answer, but only requires the ugly #ifdef's in one header file.