c files inside a c++ program - c++

#include <iostream>
#include <string>
#include <vector>
extern "C"{
#include "sql.c"
}
class ReportsSync{
public:
string getQuery();
bool testQuery(string);
};
if i have a cpp file like tis, rather a .h file like this, wud i be able to call functions defines in sql.c as usual, like i am calling c++ functions?
for eg: if sql.c has a function named foo, which returns a datatype defines in sql.c itself, can i use the returned datatype inside maybe the testQuery(), manipulate it or give it to the next function?

For #include directives the preprocessor does just a text replacement. It is like you copy all text from sql.c to your source file.
So yes you can call the functions defined in sql.c.
The only thing I know of where care is required is if your C functions take function pointers as parameters to provide a callback. You should not throw exceptions in such a callback because C does not know about C++ exceptions.
However as already pointed out in the comments it is more common to #include header files. So you can use the functions of sql.h in more than one compilation unit (.c file).

Just one thing (too large to put in a comment).
Adding extern "C" { <SOMETHING> } to a C++ source does not automagically make that SOMETHING C. It is still C++, but the interface from that SOMETHING follows C rules instead of C++ rules.
#ifndef __cplusplus
/* plain old C */
int y(void) {
return sizeof 'a';
}
#else
/* C++ */
#include <iostream>
extern "C" {
int y(); /* y is defined above, compiled with a C compiler */
int x() {
return sizeof 'a';
}
}
int main() {
std::cout << "regular sizeof 'a' is " << sizeof 'a' << std::endl;
std::cout << "extern \"C\" sizeof 'a' is " << x() << std::endl;
std::cout << "plain old C sizeof 'a' is " << y() << std::endl;
}
#endif
Compilation for the program above saved as "c++c.src" and test run
$ gcc -std=c89 -pedantic -c -xc c++c.src -o y.o
$ g++ y.o -pedantic -xc++ c++c.src
$ ./a.out
regular sizeof 'a' is 1
extern "C" sizeof 'a' is 1
plain old C sizeof 'a' is 4

Related

Namespace resolution inside preprocessor

I have a .h header shared among a C executable and a large C++ codebase.
#ifdef __cplusplus
namespace my {
#endif
typedef int my_t;
#define MY_OH_MY sizeof(my_t)
typedef my_t alias_t;
// plenty of other typedefs which push me to keep only
// these two bracing #ifdef __cplusplus ...
#ifdef __cplusplus
} // namespace
#endif
The C source works well with the exclusion.
#include "my.h"
int main(int argc, char ** argv)
{
my_t m = 1;
alias_t a = 2;
m += MY_OH_MY;
return 0;
}
However the CXX source fails under Gnu compiler:
#include "my.h"
int main(int argc, char ** argv)
{
my::my_t m = 1;
my::alias_t a = 2;
m += MY_OH_MY;
return 0;
}
my.h:7:25: error: ‘my_t’ was not declared in this scope; did you mean ‘my::my_t’?
7 | #define MY_OH_MY sizeof(my_t)
Basically because (?) at preprocessor time are namespace still not a thing ?
I was expecting that in any case it would have fallen within the namespace { } enclosing group.
I can surely change it to the following, but I still cannot figure out why it doesn't work.
#ifdef __cplusplus
#define MY_OH_MY sizeof(my::my_t)
#else
#define MY_OH_MY sizeof(my_t)
#endif
You cannot use namespaces (as it is not a feature of C language) in C identifiers that must be accessed from C. Indeed, you must declare those specially in order for the compiler not to mangle the names. You can only use them in C++, but be carefull as to share code with C, you must inform the C++ compiler which routines and what identifiers will be visible from C (the compiler mangles the names in a different way to include info about operator definitions, parameter lists and overloading, and namespaces) resulting in identifiers completely cryptic to the programmer.
To see an example, just write this function:
char *function1(char *parameter1, int parameter2)
{
return 0;
}
and compile it as C language (naming the file with .c suffix) and with C++ language (using .cc as file suffix). Then use nm(1) to see the names the compiler used to name your function.
###As C code (in file func.c):
$ make func.o
cc -O2 -pipe -c func.c -o func.o
$ nm func.o
0000000000000000 T function1
$ _
###Now as C++ code (in file func.cc):
$ make func.o
c++ -O2 -pipe -c func.cc -o func.o
$ nm func.o
0000000000000000 T _Z9function1Pci
$ _
The _Z indicates something to the compiler, the 9 indicates an identifier 9 characters long (function1), The P is for a pointer, c is for char and i if for integer parameters.
If you have compiled it in C++, but declared it inside an extern "C" { } block, then the name would have been the same as in the first example, but you should not be able to define another function with name function1 and different parameter list, as there's already a C function named function1:
#ifdef __cplusplus
extern "C" {
#endif
/* C++ functions that will be accessible from C code, or C function
* declarations that will be accessed from C++ code, depending on which
* source you include this code */
#ifdef __cplusplus
} /* extern "C" */
#endif

Compiling extern "c" code with array parameters in gcc

I'm trying to include some C function in a C++ program.
I get some issue with a function declaration that contains array as parameter.
extern "C" {
double Test( int nVar1, double f[nVar1] ) {
return f[nVar1-1];
}
}
int main() {
cout << "!!!Hello World!!!" << endl;
double f[2] = {1.0,2.0};
Test(2, f);
return 0;
}
I get following errors
'f' was not declared in this scope
'nVar1' was not declared in this scope
use of parameter outside function body before ']' token
I use Atollic 8.0 (GCC and C -std=gnu11)
Any help will welcome
Thank-you
extern "C" isn't for compiling c inside cpp source. It's only to use ABI of C inside cpp source/header: mangling, calling conventions, exception handling... (thanks to Ajay Brahmakshatriya)
By mangling, I want to say the internal unique name of function used by compiler/linker. C mangling is really different to c++ mangling, and so not compatible. To find C function inside c++, you have to say to compiler/linker under which internal unique name the function is known.
extern "C" only switches which ABI has to be used, including mangling used to create internal unique name and how function has to be called, not to switches compilation mode.
If you really want to compile c code, you have to put your code inside a c source file and compile it separately. And use extern "C"to declare function in cpp environment, to allow c++ code to use it. BUT declaration of function has to be compatible with c++, and double Test( int nVar1, double f[nVar1] ) isn't.
function.c, compile with gcc -c:
double Test( int nVar1, double f[] ) {
return f[nVar1-1];
}
function.h, compatible c and c++:
#ifndef _FUNCTION_H
#define _FUNCTION_H
#ifdef __cplusplus
extern "C" {
#endif
double Test( int nVar1, double f[] );
#ifdef __cplusplus
}
#endif
#endif
main.cpp, compile with g++ -c:
#include "function.h"
int main() {
cout << "!!!Hello World!!!" << endl;
double f[2] = {1.0,2.0};
Test(2, f);
return 0;
}
And finally, link everything with g++ linker:
g++ function.o main.o -o my_program
See example here:
C++ source, compilation c, compilation c++ and linkage
C source
The problem is with array size. It cannot be variable, should be const. If you need to pass an array of variable size then just pass the pointer to its first element:
double Test( int nVar1, double * f) {
What do you recommend to compile with g++ a such C function without having to rewritte the full code included in this legacy function
#ifdef __cplusplus
extern "C" {
#endif
int ComputedF(int nPoints, int nFunc, double x[], double f[nPoints][nFunc], double df[nPoints][nFunc])
#ifdef __cplusplus
}
#endif
Thank-you

Call C++ function in my C program [duplicate]

I know this.
Calling C function from C++:
If my application was in C++ and I had to call functions from a library written in C. Then I would have used
//main.cpp
extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.
This wouldn't mangle the name C_library_function and linker would find the same name in its input *.lib files and problem is solved.
Calling C++ function from C???
But here I'm extending a large application which is written in C and I need to use a library which is written in C++. Name mangling of C++ is causing trouble here. Linker is complaining about the unresolved symbols. Well I cannot use C++ compiler over my C project because thats breaking lot of other stuff. What is the way out?
By the way I'm using MSVC
You need to create a C API for exposing the functionality of your C++ code. Basically, you will need to write C++ code that is declared extern "C" and that has a pure C API (not using classes, for example) that wraps the C++ library. Then you use the pure C wrapper library that you've created.
Your C API can optionally follow an object-oriented style, even though C is not object-oriented. Ex:
// *.h file
// ...
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
typedef void* mylibrary_mytype_t;
EXTERNC mylibrary_mytype_t mylibrary_mytype_init();
EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype);
EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param);
#undef EXTERNC
// ...
// *.cpp file
mylibrary_mytype_t mylibrary_mytype_init() {
return new MyType;
}
void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {
MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);
delete typed_ptr;
}
void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {
MyType* typed_self = static_cast<MyType*>(untyped_self);
typed_self->doIt(param);
}
I would do it in the following way:
(If working with MSVC, ignore the GCC compilation commands)
Suppose that I have a C++ class named AAA, defined in files aaa.h, aaa.cpp, and that the class AAA has a method named sayHi(const char *name), that I want to enable for C code.
The C++ code of class AAA - Pure C++, I don't modify it:
aaa.h
#ifndef AAA_H
#define AAA_H
class AAA {
public:
AAA();
void sayHi(const char *name);
};
#endif
aaa.cpp
#include <iostream>
#include "aaa.h"
AAA::AAA() {
}
void AAA::sayHi(const char *name) {
std::cout << "Hi " << name << std::endl;
}
Compiling this class as regularly done for C++. This code "does not know" that it is going to be used by C code. Using the command:
g++ -fpic -shared aaa.cpp -o libaaa.so
Now, also in C++, creating a C connector:
Defining it in files aaa_c_connector.h, aaa_c_connector.cpp. This connector is going to define a C function, named AAA_sayHi(cosnt char *name), that will use an instance of AAA and will call its method:
aaa_c_connector.h
#ifndef AAA_C_CONNECTOR_H
#define AAA_C_CONNECTOR_H
#ifdef __cplusplus
extern "C" {
#endif
void AAA_sayHi(const char *name);
#ifdef __cplusplus
}
#endif
#endif
aaa_c_connector.cpp
#include <cstdlib>
#include "aaa_c_connector.h"
#include "aaa.h"
#ifdef __cplusplus
extern "C" {
#endif
// Inside this "extern C" block, I can implement functions in C++, which will externally
// appear as C functions (which means that the function IDs will be their names, unlike
// the regular C++ behavior, which allows defining multiple functions with the same name
// (overloading) and hence uses function signature hashing to enforce unique IDs),
static AAA *AAA_instance = NULL;
void lazyAAA() {
if (AAA_instance == NULL) {
AAA_instance = new AAA();
}
}
void AAA_sayHi(const char *name) {
lazyAAA();
AAA_instance->sayHi(name);
}
#ifdef __cplusplus
}
#endif
Compiling it, again, using a regular C++ compilation command:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Now I have a shared library (libaaa_c_connector.so), that implements the C function AAA_sayHi(const char *name). I can now create a C main file and compile it all together:
main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Compiling it using a C compilation command:
gcc main.c -L. -laaa_c_connector -o c_aaa
I will need to set LD_LIBRARY_PATH to contain $PWD, and if I run the executable ./c_aaa, I will get the output I expect:
Hi David
Hi James
EDIT:
On some linux distributions, -laaa and -lstdc++ may also be required for the last compilation command. Thanks to #AlaaM. for the attention
Assuming the C++ API is C-compatible (no classes, templates, etc.), you can wrap it in extern "C" { ... }, just as you did when going the other way.
If you want to expose objects and other cute C++ stuff, you'll have to write a wrapper API.
You will have to write a wrapper for C in C++ if you want to do this. C++ is backwards compatible, but C is not forwards compatible.
export your C++ functions as extern "C" (aka C style symbols), or use the .def file format to define undecorated export symbols for the C++ linker when it creates the C++ library, then the C linker should have no troubles reading it
#include <iostream>
//////////////
// C++ code //
//////////////
struct A
{
int i;
int j;
A() {i=1; j=2; std::cout << "class A created\n";}
void dump() {std::cout << "class A dumped: " << i << ":" << j << std::endl;}
~A() {std::cout << "class A destroyed\n";}
};
extern "C" {
// this is the C code interface to the class A
static void *createA (void)
{
// create a handle to the A class
return (void *)(new A);
}
static void dumpA (void *thisPtr)
{
// call A->dump ()
if (thisPtr != NULL) // I'm an anal retentive programmer
{
A *classPtr = static_cast<A *>(thisPtr);
classPtr->dump ();
}
}
static void *deleteA (void *thisPtr)
{
// destroy the A class
if (thisPtr != NULL)
{
delete (static_cast<A *>(thisPtr));
}
}
}
////////////////////////////////////
// this can be compiled as C code //
////////////////////////////////////
int main (int argc, char **argv)
{
void *handle = createA();
dumpA (handle);
deleteA (handle);
return 0;
}
You can prefix the function declaration with extern “C” keyword, e.g.
extern “C” int Mycppfunction()
{
// Code goes here
return 0;
}
For more examples you can search more on Google about “extern” keyword. You need to do few more things, but it's not difficult you'll get lots of examples from Google.

Include and compile C++ header file from C

I have a C++ file and its header file. I need to include this header file in a C code and use the functions in it.
When the cpp.h file is compiled through main.c, compilation fails because of the C++ linkage.
On using the macro __cplusplus stream and string are not resolved, is there some way to compile the cpp.h file through and execute?
I have given a outline of my code only.
C++ header file cpp.h:
struct s1
{
string a;
string b;
};
typedef struct s1 s2;
class c1
{
public:
void fun1(s2 &s3);
private:
fun2(std::string &x,const char *y);
};
C++ file cpp.cpp:
c1::fun1(s2 &s3)
{
fstream file;
}
c1::fun2(std::string &x,const char *y)
{
}
C file main.c:
#include "cpp.h"
void main()
{
c1 c2;
s1 structobj;
c2.fun1(&structobj);
printf("\n value of a in struct %s",structobj.a);
}
Basically, you can't.
You need to put only C functions in your header file.
You put them in a extern "C" block this way:
#ifdef __cplusplus
extern "C"
{
#endif
extern void myCppFunction(int n);
#ifdef __cplusplus
}
#endif
The extern "C" block is not recognized by a C compiler, but the C++ compiler need it to understand he have to consider functions inside as C functions.
In your cpp file you can define myCppFunction() so that she uses any C++ code, you will get a function C code can use.
Edit: I add a full example of how to link a program with a C main() using some C++ functions in a module.
stackoverflow.c:
#include "outputFromCpp.h"
int main()
{
myCppFunction(2000);
return 0;
}
outputFromCpp.h:
#ifndef OUTPUT_FROM_CPP_H
#define OUTPUT_FROM_CPP_H
#ifdef __cplusplus
extern "C"
{
#endif
extern void myCppFunction(int n);
#ifdef __cplusplus
}
#endif
#endif
outputFromCpp.cpp:
#include "outputFromCpp.h"
#include <iostream>
using namespace std;
void myCppFunction(int n)
{
cout << n << endl;
}
Compiling and linking:
gcc -Wall -Wextra -Werror -std=gnu99 -c stackoverflow.c
g++ -Wall -Wextra -Werror -std=c++98 -c outputFromCpp.cpp
g++ -o stackoverflow.exe stackoverflow.o outputFromCpp.o -static
You cannot link such a program with gcc.
If you want to link with gcc you need to put all the C++ code in a shared library, I don't put an example as it would be a bit platform dependent.
This can be done by introducing a wrapper to c++ function. The C function calls the wrapper function which inturn calls the desired C++ function (including member functions).
More details are available here

How do I share variables between C and C++ code?

I'm working on a C++ project that implements C code and I'm stuck on a segmentation fault. The segfault occures when I try to access a global C variable in my C++ code.
Overview of the code:
I have a single c file called video_stage.c with the following code snippet:
#include "video_stage.h"
uint8_t* pixbuf_data = NULL; //pointer to video buffer
vp_os_mutex_t video_update_lock = PTHREAD_MUTEX_INITIALIZER;
C_RESULT output_gtk_stage_transform( void *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
{
vp_os_mutex_lock(&video_update_lock);
/* Get a reference to the last decoded picture */
pixbuf_data = (uint8_t*)in->buffers[0];
vp_os_mutex_unlock(&video_update_lock);
return (SUCCESS);
}
This function is periodically called by other C code and updates the pixbuf_data pointer witch points to an RGB videoframe.
It's header file video_stage.h:
#ifndef _IHM_STAGES_O_GTK_H
#define _IHM_STAGES_O_GTK_H
#ifdef __cplusplus
extern "C" {
#endif
#include <config.h>
#include <VP_Api/vp_api_thread_helper.h>
#include <VP_Api/vp_api.h> //hier zit vp_os_mutex in geinclude
PROTO_THREAD_ROUTINE(video_stage, data);
#ifdef __cplusplus
}
#endif
extern uint8_t* pixbuf_data;
extern vp_os_mutex_t video_update_lock;
#endif // _IHM_STAGES_O_GTK_H
The header file contains the extern declaration of the pixbuf_data pointer.
And here the cpp file: device.cc:
#include <iostream>
#include "video_stage.h"
int ardrone_update(ardrone_t *d)
{
uint8_t x;
x = pixbuf_data[0]; //no problem here, this is executed
std::cout << 5 << std::endl; //this is executed too
std::cout << x << std::endl; //segfault occures here
}
When the function in the cpp file is called (by other cpp code), a segfault occures at the cout instruction that prints x.
When I do a printf of the first element of the buffer in the c file, I get what I expect.
I'm sure it has something to do with the mixing of c and c++ code, but according to my research I've done the stuff to make both c and c++ code compatible here.
In C++ code pixbuf_data defined in a C source must be declared with C linkage:
extern "C" uint8_t* pixbuf_data;
Without extern "C" the C++ code must not link, unless there is another (duplicate) definition of pixbuf_data with C++ linkage.
get yourself a debugger and run your program under that. The tracing code does not tell you at all where the segfault appears, IO is slow.
In the code that you show us, you don't seem to allocate memory for pixbuf_data. Anything can happen when you access that without assigning a valid pointer to it.
I am trying to share variable between C project and c++ project. but when i build my solution i got "error LNK2001: unresolved external symbol "struct configuration g_conf ". This what i did:
==== In C project ==
I create a header file and on it i create my struct
typedef struct{ int maxUser; }Configuration;
extern Configuration conf;
==== In C++ project =======
In the main file :
#include "../ProjectC/header.h"
int main(){ conf.maxUser = 10; }