Mixing c++ string with c - c++

I have a c and cpp file
mycpp.cpp
fun()
{
//code goes here....
}
mycpp.h
#include<string>
struct str{
std::string a;
};
func();
myc.c
#include "mycpp.h"
func();
//with other c codes..
This is a part of large code list. So it gets compiled via c++ and c.
My problem is when mycpp.h is compiled through myc.c (which is included in myc.c) , Compiler throws an error saying fatal error: string: No such file or directory
Is there some wrapper mechanism to overcome this scenario?

You cannot include a C++ header file in a C file.
Declare the function func() with C linkage, and refer to it as an extern function inside your C file.
Example:
mycpp.cpp
void func(void)
{
/* foo */
}
mycpp.h
extern "C" void func(void);
myc.c
extern void func(void);
/* you can now safely call `func()` */
You cannot use std::string in C, if you want to access your string, you have to pass it accordingly into your C code, by passing it a char const* with the contents of the string. You can get access to this string by calling std::string::c_str(). You can read more about c_str() here.

Related

how to call C++ functions in C layer within the same project?

I have a C++ header and cpp files like abc.hpp and abc.cpp which has 2 classes that is class A and class B, am trying to write a C layer containing different methods which calls the C++ layer methods, to call the C++ methods I need to create the instance of Class A and then use this instance to call C++ methods, I have created a C layer but tried different ways to create an instance of class B but it was not possible.
This is ABC.hpp
#ifndef ABC_HPP
#define ABC_HPP
namespace utils {
using std::vector;
using std::string;
class __declspec(dllexport) A
{
protected:
string m_color;
string m_type;
public:
A() {
// TODO: Complete the constructor by intializing everything
m_color = "";
m_type = "";
}
void setColor(string icolor){m_color = icolor;}
void setType(string itype){m_type = itype;}
string getColor(){return m_color;}
string getType() {return m_type;}
virtual ~A() {};
};
class __declspec(dllexport) B
{
// Member Variables
protected:
string file_name;
string place_name;
public:
void setFilename(fname){file_name = fname;}
void setPlaceName(pname){place_name = pname;}
string getFilename(){return file_name;}
string getplaceName() {return place_name;}
void getRes();
};
};
#endif
Similarly we have ABC.cpp
Next I create the C layer xyz_c.h
#ifndef XYZ_H
#define XYZ_H
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) int getPlaceNames(char** oNames);
#ifdef __cplusplus
}
#endif
#endif
Next I create XYZ.cpp
#include "XYZ.h"
#include "ABC.h"
#ifdef __cplusplus
extern "C" {
#endif
int getResults(char** oNames)
{
//here I need to create the instance of B to Call C++ layer getRes()
}
#ifdef __cplusplus
}
#endif
You cannot. C++ was designed to allow it to use the whole set of C legacy code already written, but the other side is not possible... simply because when C was designed there was no C++ available, and C doesn't have constructs as C++ has to be able to link routines written in C.
This means that if you want to combine C and C++ code, the program must be linked as a C++ program (built as) and you can include every routine you want (you can compile individual modules as C modules) but you have to access them from the C++ code including a extern "C" linkage statement in the C++ code (and never the reverse)
C++ has a naming convention for methods and c++ functions that includes information in the name about the types and number of parameters to allow for overloading and to include the object instance in the parameter list. This is simply unknown for a C compiler, so you cannot easily guess the name that the linker uses for something so simple as a void f(void) function (it can be something like 1f4void (yes, starting with a digit) making it impossible to be accessed from C (as C identifiers must start with a letter or underscore). If you declare f as extern "C" f(void), then you can call it from C modules, and it can even be implemented in C (and compiled in c), and the linker will know it as _f (or f is in use today also, depending on the compiler)
You can even write the int main(int argc, char **argv) funtion as a C function, but when you link it, you will need to use the C++ linker, if you want your program to include C++ code.
The proper way to do this is as follows. In your "C" interface code, you should have functions matching the c++ interface with the addition of a void* parameter. This parameter will be used to hold the instance for future usage by XYZ.
SO I would add a abc.c, with definitions as:
void setFilename(void* b, char *fname){
((B*)b)->setFilename(fname);
};
of course you will need to define also creator function such as:
void* CreateB(){
return (void*)new B();
}

Passing a file as a parameter to a C++ method from Swift

I am trying to call some C++ code in a Swift application. I did not write the C++ nor do I have control over it.
I have created a C++ wrapper to handle the calls from Swift. I also added some test functions within the C++ files to verify that I am calling the C++ from Swift. Those functions simply return an int.
In the C++ header code there is a function defined as follows:
class GlobeProcessor {
public:
void readFile(ifstream &inputFile);
// ...
};
In my wrapper I have defined the function as follows:
extern "C" void processGlobe(ifstream &file) {
GlobeProcessor().readFile(file);
}
The confusing part is how to reference this in my bridging header. Currently the bridging header contains the following:
// test function
int getNumber(int num);
void processGlobeFile(ifstream &file);
The test function succeeds, so I am able to access the C++ from Swift. However, adding a declaration for processGlobeFileto the bridging header produces the following compile error:
Unknown type name 'ifstream'
I have tried unsuccessfully to add the appropriate imports to the bridging header. I am not a seasoned C++ guy, so i don't really know if I'm approaching this in the correct manner. Can somebody help me to understand how to pass a file as a parameter to a C++ method from Swift?
Thanks!
Swift can't import C++. ifstream is a C++ class and the parameter is also a C++ reference. Neither of these are going to work with Swift.
You have to write a C function that wraps your C++ call and treats your ifstream object as an opaque reference.
Also your wrapper function has to be declared extern "C" not just defined that way, otherwise other C++ files that include the header will assume it has name mangling.
Something like this might work but I haven't tested it at all:
// header
#if !defined _cplusplus
typedef struct ifstream ifstream; // incomplete struct def for C opaque type
#else
extern "C" {
#endif
int getNumber(int num);
void processGlobeFile(ifstream *file); // note you need to use a pointer not a reference
#if defined __cplusplus
} // of the exten C
#endif

loadlibrary and C++ header files

I wrote some functions and create dll by C++ codes & used some of the C++ header files. But I found loadlibrary only supports C header files and I get this error:
Error using loadlibrary (line 419)
Failed to preprocess the input file.
Output from preprocessor is:LargeBaseConvertorClass.h
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\eh.h(26) : fatal error C1189: #error : "eh.h is only for
C++!"
I dont want to change my codes and I dont want to use mex functions.
How can I use my C++ dll in matlab? (I need a lot)
Thanks.
Ya Ali.
I've done two things to handle this before.
The first is to write a C wrapper around the C++ code.
//foo_c_wrapper.h
#ifndef FOO_C_WRAPPER_H
#define FOO_C_WRAPPER_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void* FOO_HANDLE;//can use a predeclared pointer type instead
FOO_HANDLE init_foo(int a);
void bar(FOO_HANDLE handle);
void destroy_foo(FOO_HANDLE** handle);
//ect
#endif
//foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
class Foo {public: Foo(int); ~Foo(); void bar();}
#ifdef __cplusplus
}
#endif
#endif
//foo_c_wrapper.cpp
#include "foo_c_wrapper.h"
#include "foo.hpp"
extern "C" {
FOO_HANDLE init_foo(int a) {return new Foo(a);}
void bar(FOO_HANLDE handle) {
Foo* foo = reinterpret_cast<Foo*>(handle);
foo->bar();
}
void destroy_foo(FOO_HANDLE** handle) {
Foo** foo = reinterpret_cast<Foo**>(handle);
delete *foo;
*foo = NULL;
}
}
The other option is to go the rout of creating a custom mex file. Unfortunately that topic is way too broad to go into details here, so I'm going to count "Creating a C++ compatable Mex File" as the summary of the following link:
http://www.mathworks.com/help/matlab/matlab_external/c-mex-file-examples.html#btgcjh1-14
I did that in the past by creating a a few C interface functions to create and manipulate the C++ objects. Doing this makes it possible to easily use C++ code from Matlab without having to modify it. As long as the header is only C, Matlab does not complain if C++ objects are created in the end.
For instance, if the class you want to use from Matlab is:
class MyClass
{
public:
double memberFunction();
};
Have a header file be (add prefix to have functions be exported):
int createObject();
double callFunction( int object );
Have the cpp file be something like:
static std::map<int,MyClass*> mymap;
int createObject()
{
MyClass* obj = new MyClass();
int pos = mymap.size();
mymap[pos] = obj;
return pos;
}
double callFunction( int obj )
{
return mymap[obj]->memberFunction();
}
Now, you can create MyClass objects and access members from Matlab.
You'll need to pass more parameters, handle map content better (check if object exists in the map and return errors if not, delete objects from the map when done...etc), but this is the general idea.

extern C and struct method

Given the following C++ code,
#ifdef __cplusplus
extern "C" {
#endif
struct foo {
void getNum() {
}
};
#ifdef __cplusplus
}
#endif
int main (int argc, char * const argv[]) {
return 0 ;
}
Is it possible to call getNum() from C?
No, since getNum is a member function, which C doesn't have.
A possible solution to that problem is to write a C++ function to return a foo instance as a foo* (where foo is changed to be an empty struct) to C (I assume this is binary compiled as C++ to which C is linking), then have a free function in C++ called foo_getNum or something, which takes a foo* (whose definition is modified for the C version to be empty) which calls getNum on it. It wouldn't be type safe though, obviously, (but taking a foo* even when foo is empty would be better than void* - thanks David).
The extern "C" has no effect on the member function: getNum() has C++ language linkage.
The C++ Language Standard states (C++03 §7.5/4):
A C language linkage is ignored for the names of class members and the member function
type of class member functions.
So, no, you cannot call this function directly from a C program (though, as others have said, you can't compile that code as C anyway because C does not have member functions). It is of course conceivable that some implementations might allow you to call this function from a C program via some implementation-specific method.
You can't call that member function from C in a portable way. You need to expose your C++ interface by flattening it.
The code you gave will not compile in C mode as C compiler doesn't support functions in struct. However you can create a function in C++ which can call this and link it with C linkage.
Create 2 files main.c and abc.cpp
Code for main.c
extern "C" void getNumCaller();
int main ()
{
getNumCaller();
return 0;
}
Code for abc.cpp
#include <iostream>
struct foo {
void getNum() {
std::cout << "calling getNum" << std::endl;
}
};
extern "C" void getNumCaller()
{
struct foo abc;
abc.getNum();
}
Compile the code :
g++ -o abc abc.cpp main.c
and you will get output:
calling getNum

How to call a c++ class and its method from a c file

I am trying to access a C++ class and call its method from a .c file.
I google this topic and find this http://developers.sun.com/solaris/articles/mixing.html
It says:
You can write extern "C" functions in C++ that access class M objects and call them from C code.
Here is a C++ function designed to call the member function foo:
extern "C" int call_M_foo(M* m, int i) { return m->foo(i); }
My question is where do I put the about line? In my C++ .h file? Or C .h file?
And it goes on and says:
Here is an example of C code that uses class M:
struct M; // you can supply only an incomplete declaration
int call_M_foo(struct M*, int); // declare the wrapper function
int f(struct M* p, int j) // now you can call M::foo
{
return call_M_foo(p, j);
}
But how/where do I create the class M in my C file?
And where do I put the above code? C .h file? C++ .h file? Or C .c file?
Thank you.
Thank you for GMan's detailed answer.
I did follow your suggestion. But I get compile error in my .c file.
main.c:33:
./some_class.h:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘’ token
./some_class.h:25: error: expected ‘)’ before ‘’ token
./some_class.h:26: error: expected ‘)’ before ‘*’ token
And here are my some_class.h line 24-26:
#ifdef __cplusplus
class M {
public:
M();
virtual ~M();
void method1(char* name, char* msg);
};
extern "C" {
#else
struct M;
#endif
/* access functions line 24-26 are here*/
M* M_new(void);
void M_delete(M*);
void M_method1(M*, char*, char*);
#ifdef __cplusplus
}
#endif
For some reason, my C compiler does not like extern "C" in GMan's original some_test.h. So I have to modify to above. It seems like the C compiler does not like/understand the struct M; line.
Any idea will be much appreciated.
Your header file, which is shared between your C and C++ code:
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method(float);
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
EXPORT_C some_class* some_class_new(void);
EXPORT_C void some_class_delete(some_class*);
EXPORT_C int some_class_some_method(some_class*, float);
Then your source file:
#include "some_foo.h"
int some_class::some_method(float f)
{
return static_cast<int>(f);
}
// access functions
EXPORT_C some_class* some_class_new(void)
{
return new some_class();
}
EXPORT_C void some_class_delete(some_class* this)
{
delete this;
}
EXPORT_C int some_class_some_method(some_class* this, float f)
{
return this->some_method(f);
}
Now compile that source, and link to it. Your C source would be something like:
#include "some_class.h"
some_class* myInstance = some_class_new();
int i = some_class_some_method(myInstance, 10.0f);
some_class_delete(myInstance);
If you're serious about mixing C and C++, you'll want macro's.
Here are some sample macro's that would make this much easier:
// in something like c_export.h
// extern "C" macro
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
// new
#define EXPORT_C_CLASS_NEW(classname) EXPORT_C \
classname * classname##_new(void)
#define EXPORT_C_CLASS_NEW_DEFINE(classname) \
EXPORT_C_CLASS_NEW(classname) \
{ return new classname (); }
// repeat as much as you want. allows passing parameters to the constructor
#define EXPORT_C_CLASS_NEW_1(classname, param1) EXPORT_C \
classname * classname##_new( param1 p1)
#define EXPORT_C_CLASS_NEW_1_DEFINE(classname, param1) \
EXPORT_C_CLASS_NEW_1(classname, param1) \
{ return new classname (p1); }
// delete
#define EXPORT_C_CLASS_DELETE(classname) EXPORT_C \
void classname##_delete( classname * this)
#define EXPORT_C_CLASS_DELETE_DEFINE(classname) \
EXPORT_C_CLASS_DELETE(classname) \
{ delete this; }
// functions
#define EXPORT_C_CLASS_METHOD(classname, methodname, ret) EXPORT_C \
ret classname##_##methodname##( classname * this)
#define EXPORT_C_CLASS_METHOD_DEFINE(classname, methodname, ret) \
EXPORT_C_CLASS_METHOD(classname, methodname, ret) \
{ return this->##methodname##(); }
// and repeat as necessary.
#define EXPORT_C_CLASS_METHOD_1(classname, methodname, ret, param1) EXPORT_C \
ret classname##_##methodname( classname * this, param1 p1)
#define EXPORT_C_CLASS_METHOD_1_DEFINE(classname, methodname, ret, param1) \
EXPORT_C_CLASS_METHOD_1(classname, methodname, ret, param1) \
{ return this->##methodname##(p1); }
And so on. Our header/source becomes:
// header
#include "c_export.h" // utility macros
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method(float);
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
EXPORT_C_CLASS_NEW(some_class);
EXPORT_C_CLASS_DELETE(some_class);
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float);
// source
#include "some_foo.h"
int some_class::some_method(float f)
{
return static_cast<int>(f);
}
// access functions
EXPORT_C_CLASS_NEW_DEFINE(some_class);
EXPORT_C_CLASS_DELETE_DEFINE(some_class);
EXPORT_C_CLASS_METHOD_1_DEFINE(some_class, some_method, int, float);
And that's much more concise. It could be made simpler (possibly) with variadic macro's, but that's non-standard and I leave that to you. :] Also, you can make macro's for normal non-member functions.
Note that C does not know what references are. If you want to bind to a reference, your best bet is probably just to write the export definition manually. (But I'll think about it, maybe we can get it automatically).
Imagine our some_class took the float by (non-const)reference (for whatever reason). We'd define the function like so:
// header
// pass by pointer! v
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float*) ;
// source
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float*)
{
// dereference pointer; now can be used as reference
return this->some_method(*p1);
}
And there we go. C would interface with references with pointers instead:
// c source, if some_method took a reference:
float f = 10.0f;
int i = some_class_some_method(myInstance, &f);
And we pass f "by reference".
You need to split it among the C++ header and implementation files.
foo.h:
extern "C" int call_M_foo(M* m, int i);
foo.cc:
extern "C" int call_M_foo(M* m, int i) {
return m->foo(i);
}
To create the object of type M, you would need a similar function:
foo.h:
struct M;
extern "C" M* create_M();
foo.cc:
extern "C" M* create_M() {
return new M;
}
You have several questions combined here so I will answer them individually.
My question is where do I put the about line? In my c++ .h file? or c .h file?
The extern "C" line goes in the C++ file. It essentially tells the compiler to
limit everything whithin the extern "C" block to the C subset of C++, and to
export functions declared in this area accordingly.
But how/where do I create the class M in my c file?
You can't. C does not have the concept of classes, and there's absolutely no
way to instantiate a class directly. You essentially have to export a C function
in your C++ file which creates the class and returns it as a pointer. Then you
can pass that pointer around your C application. You can't actually modify the
class directly in your C application, because C does not support classes, and
your C++ compiler may insert "hidden" variables for bookkeeping inside the
actual declaration of the class.
And where do I put the above code?
The piece of code that uses a structure pointer goes in the C file. You are
forced to use a structure pointer because C does not support classes at all.
You can put function calls using that function anywhere in a C implementation
file, just like normal C function calls.
All the information you need is in the link you provide. You just need to understand that there needs to be a strict separation between C and C++ code.
C++ code can call any C code.
C code usually cannot call any C++ code.
C functions can be implemented by C++ code.
The key part to understand is that the C and C++ compilers mangle function names when making object files in different ways, so they would normally not be able to interoperate (at link time), except that C++ can be prompted to know the difference by using extern "C"
The prototype:
void f(int); might be mangled by a C compiler to: _f, but a C++ compiler might choose a very different name eg f_int, and so the linker would not know they are supposed to be the same.
However:
extern "C" void f(int);
would be mangled by a C++ compiler to _f, but a C compiler would choke on the extern "C". To avoid this you should used something like this:
#ifdef __cplusplus
extern "C" {
#endif
void f(int);
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
Now the whole of the above section can live in a .h file and is, as the sun.com article states, a mixed-language header.
This means that a .c or .cpp file can #include this header and code can call f();
and either a .c or .cpp file can #include this header and implement it:
void f()
{
}
Now the good bit is that a .cpp file can implement this to call any C++ code it likes.
Now to answer your specific questions:
The first code sample can only go in a .cpp file.
The second code sample can only go in a .c file.
Additionally class M must be declared and defined in C++ files only.
The site you have linked to has the answer already:
You can declare function print in a
header file that is shared by C and
C++ code:
#ifdef __cplusplus extern "C"
#endif int print(int i, double d);
You can declare at most one function
of an overloaded set as extern "C"
Here is the example C header for the
wrapper functions:
int g_int(int);
double g_double(double);
Basically, there can be a header shared between the two that declares the function prototype, adding the extern "C" modifier if you are in C++ to ensure the function can be accessed in an object from C. You define the body of the function later on in the C++ code as usual, if necessary inside a class etc, and you use the function in C like normal.