C++ extern not found when in header - c++

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

Related

stdint header for functions exported from dll

I have a header for exporting some methods from a DLL which can be used both from C and C++ code:
#ifdef __cplusplus
extern "C"
{
#endif
API_EXPORT uint32_t __cdecl GetSomeValue();
#ifdef __cplusplus
}
#endif
and for uint32_t, I need to include a header, but which one is correct?
Option 1: <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
Option 2:
#ifdef __cplusplus
extern "C"
{
#endif
#include <cstdint>
Option 3: both.
#ifdef __cplusplus
extern "C"
{
#include <cstdint>
#else
#include <stdint.h>
#endif
You... just include the header.
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
API_EXPORT uint32_t __cdecl GetSomeValue();
#ifdef __cplusplus
}
#endif
You don't need to use extern "C" {} around built-in headers. (Sometimes you might find libraries that do need it)
Your option 2 generally will not work in conjunction with C compilers, so that's out. Your option 1, or the variation presented in #user253751's answer, should be fine, but if you are concerned with protecting against buggy C, C++, or standard library implementations then I would go with this variation on your option 3:
#ifdef __cplusplus
#include <cstdint>
extern "C"
{
#else
#include <stdint.h>
#endif

Undefined reference when use c-function from c++ file

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!

Warning: 'void checkGlError(const char*)' used but never defined

I'm compiling a Shared library using Android NDK r6b. All classes are C++.
I have the following two classes:
Utils.hpp
#ifdef USE_OPENGL_ES_1_1
#include <GLES/gl.h>
#include <GLES/glext.h>
#else
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif
#include <android/log.h>
// Utility for logging:
#define LOG_TAG "ROTATEACCEL"
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
static void checkGlError(const char* op);
#ifdef __cplusplus
}
#endif
Utils.cpp
#include "Utils.hpp"
#ifdef __cplusplus
extern "C" {
#endif
static void checkGlError(const char* op) {
for (GLint error = glGetError(); error; error
= glGetError()) {
LOGI("after %s() glError (0x%x)\n", op, error);
}
}
#ifdef __cplusplus
}
#endif
When I want to use this function in other C++ files I #include "Utils.hpp". But, in those files I get an error:
undefined reference to `checkGlError'
Why am I getting this warning?
You've made it static. It only lives in that specific translation unit therefore. The solution is to remove the static keyword.
The warning is telling you that in the header file you "promised" there would be a definition in that translation unity if one was needed, but one has not been provided and it was needed.
static void checkGlError(const char* op);
It is a static function, that means, it has internal linkage, and therefore cannot be called from another translation unit.
Remove the static keyword from it's declaration as well as from it's definition, and it would work fine.

Call C++ class member function from C (Visual Studio)

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();
}
}

Using C code from C++ using autotools

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.