Reputation: 7304
I have gstdsexample.so
, a C++ library.
Inside, it has two global variables that I'd like to share between the library and the main C program.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int *ptr;
Test two scenarios.
Scenario 1
sharedata.h
#ifndef __SHARE_DATA_H__
#define __SHARE_DATA_H__
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int *ptr;
#endif /* __SHARE_DATA_H__ */
Include sharedata.h
in gstdsexample.cpp
and main.c
.
Compilation OK but I get a segmentation fault when gstdsexample.cpp
writes data to *ptr
.
Scenario 2
Declare two variables in
gstdsexamle.cpp
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int *ptr;
Then declare as extern
in main.c.
extern pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
extern int *ptr;
Now I have undefined reference errors to the two variables when compiling main.c
.
Scenario 3:
#ifndef __SHARE_DATA_H__
#define __SHARE_DATA_H__
#include <stdio.h>
#include <pthread.h>
extern "C" {
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int *ptr;
}
#endif /* __SHARE_DATA_H__ */
Then include sharedata.h
in gstdsexample.cpp
and main.c
.
Compiling for cpp lib is fine.
But compiling for main.c has errors as
error: expected identifier or ‘(’ before string constant
extern "C" {
^~~
deepstream_app_main.c: In function ‘all_bbox_generated’:
deepstream_app_main.c:98:24: error: ‘mutex’ undeclared (first use in this function); did you mean ‘GMutex’?
pthread_mutex_lock( &mutex );
^~~~~
GMutex
deepstream_app_main.c:98:24: note: each undeclared identifier is reported only once for each function it appears in
deepstream_app_main.c:101:21: error: ‘ptr’ undeclared (first use in this function); did you mean ‘puts’?
printf("%d ", *(ptr+x));
How to share variables between C++ and C source files?
Upvotes: 0
Views: 938
Reputation: 12668
Scenario 1 and scenario 2 are invalid because C++ mangles the names of the C++ identifiers to allow for identifier overloading.
Scenario 3 fails because the extern "C" { }
constructor is a syntactic construction valid only in C++ and it is not legal in C. To be able to do this, you need to parse
extern "C" {
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int *ptr;
}
to indicate the C++ compiler that they are variables to be compatibilized with C calling schema.
But the C language is not aware of something coming from a different language so in C, those declarations must appear as:
extern pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
extern int *ptr;
in the header file, but without the invalid syntax.
An approach has been exposed in anotheer answer, so I will not extend explaining what is said there, just to say that __cplusplus
macro is defined by the compiler automatically when it is acting as a C++ compiler, so that can be used as in the other answer to allow the header file to share C and C++ declarations.
Upvotes: 0
Reputation: 9682
in a header file... gstdsexamle.h
// disable name mangling in C++
#ifdef __cplusplus
extern "C" {
#endif
// declare your two vars in the header file as extern.
extern pthread_mutex_t mutex;
extern int *ptr;
#ifdef __cplusplus
}
#endif
in gstdsexamle.c
#include "gstdsexamle.h"
/* only initialise here */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int *ptr;
in main.c
#include "gstdsexamle.h"
Thats all you need. mutex & ptr are now available in main.cpp/main.c
Upvotes: 1