0

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?

5
  • 1
    The variables need to be in extern "C" { ... } blocks if you want to share them with C code. Commented Nov 24, 2021 at 4:00
  • I tested extern "C" {} in sharedata.h. Added Scenario 3 in original post. But error compiling main.c. cpp library is fine. Commented Nov 24, 2021 at 4:41
  • #ifdef __cplusplus extern "C" { #endif Commented Nov 24, 2021 at 4:42
  • The C compiler is complaining about extern "C" (which is a C++ construct). You need to check for __cplusplus to avoid that. (and just use extern instead) Commented Nov 24, 2021 at 4:44
  • #ifdef __cplusplus extern "C" { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int *ptr; } #endif /* __SHARE_DATA_H__ */ I did like that but still same error Commented Nov 24, 2021 at 4:47

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

gstdsexample lib is fine. But main.c has undefined errors as `undefined reference to mutex and undefined reference to ptr'
I also need to declare this in main.c pthread_mutex_t mutex; int *ptr;
0

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.

2 Comments

I've seen __cplusplus__ macro referenced in older (25+ years) code, but I think compilers define __cplusplus nowadays. Do you know where the __cplusplus__ with trailing underscores comes from?
That's a typo, my apologies for that. Now it's correct. It's possible that old compilers define it, but today, the standard only talks of the one without trailing underscores.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.