C&c++--c function and C + + function calling each other problem

Source: Internet
Author: User

C C + + calls each other

Merging C and C + + in a project is sometimes unavoidable, and it might be a problem when calling the other's function, but as long as my C code and my C + + code are compiled successfully, the rest is not a problem. Recently in the main program is the C language, while calling C + + function functions, C + + *.h header files can be found, functional functions are also defined, most importantly, when the C + + is compiled separately, there is absolutely no problem, but when the main program's C calls C + + function function, It is always suggested that the function is undefined (undefined), and the source of this analysis is the problem with mixed calls.
Here's the key: we'll be able to solve the problem by adding the following code to the *.h and *.cpp of C + +.
#ifdef __cplusplus
extern "C" {
#endif
A section of code
#ifdef __cplusplus
}
#endif
What does this kind of code mean? First of all, __cplusplus is a custom macro in CPP, then the definition of this macro means that this is a CPP code, that is, the above code means: If this is a piece of CPP code, then add the extern "C" {and} to process the code in it.
To understand why the extern "C" is used, you have to start with the overloaded handling of the function from CPP. In C + +, in order to support overloading mechanism, in compiling the generated assembly code, the name of the function to do some processing, such as the return type of the function and so on. In C, it's just a simple function name that doesn't include any other information. That is, C + + and C handle the resulting function names differently. The purpose is to implement the problem of mutual invocation between C and C + +.

The realization of c.h
#ifndef _c_h_
#define _c_h_
#ifdef __cplusplus
extern "C" {
#endif
void C_fun ();
#ifdef __cplusplus
}
#endif
#endif
-----------------------------------
The realization of C.C
# include "C.h"
void C_fun ()
{
}
------------------------------------
Call the C_fun () in C.C in Cpp.cpp
The realization of Cpp.cpp
# include "C.h"
int main ()
{
C_fun ()
}
Where __cplusplus is a reserved macro definition for the C + + compiler. This means that the C + + compiler thinks the macro is already defined.
So the key is extern "C" {}//Here is to tell you that __cplusplus is not the most important, it is important that extern "C" {}
extern "C" is to tell C + + compile the device in parentheses is compiled according to the C obj file format, to connect the word according to C's naming rules to find.
==========================
So in C, how do you call the function Cpp_fun () in C + +? This is the problem I mentioned above, that is, write the main program in C, and then call the C + + function function.
Because C + + is available first, it can only be considered in C + + code.
Adding a function or variable in C + + may be called by a file in C, which should be written in the extern "C" {}
Just add the code, and the header file is added, because it might be called in C + +.
--------------------------------------
The realization of Cpp.h
#ifndef _c_h_
#define _c_h_
#ifdef __cplusplus
extern "C" {
#endif
void Cpp_fun ();
#ifdef __cplusplus
}
#endif
#endif
.-------------------------------------------
The realization of Cpp.cpp
extern "C" {//Tell c+++ compiler, the extension number is compiled according to C's naming rules
void Cpp_fun ()
{
.....
}
}
C and C + + treat functions differently. extern "C" is a means to enable C + + to invoke C-writing library files, and if you want to use C as the compiler prompts to handle functions, then use extern "C" to illustrate.




The following is an excerpt from an article about the extern "C" description;

Why add extern "C" when you call a function compiled by the C compiler in a C + + program?

First, as extern is a keyword that indicates the scope (visibility) of functions and global variables in the C/s + + language, the keyword tells the compiler that its declared functions and variables can be used in this module or in other modules.
Typically, the function and global variables that this module provides to other modules in the header file of the module are declared with the keyword extern. For example, if module B is to reference the global variables and functions defined in module A, only the header file of module A can be included. In this way, when a function in module A is called in Module B, in the compile phase, Module B cannot find the function, but it does not error; it will find this function in the connection phase from the target code generated by module a compilation.
The extern "C" is a connection declaration (linkage declaration), and the variables and functions modified by the extern "C" are compiled and concatenated in C language, to see how C + + is compiled for a function of a similar type:
As an object-oriented language, C + + supports function overloading, whereas programming language C is not supported. Functions are compiled in C + + with different names in the symbol library than in the C language. For example, suppose a function is prototyped as:
void foo (int x, int y);
The function is compiled by the C compiler in the symbol library with the name _foo, while the C + + compiler produces names like _foo_int_int (different compilers may generate different names, but all use the same mechanism, and the resulting new name is called "Mangled Name").
_foo_int_int such a name includes the function name, function parameter number and type information, C + + is this mechanism to implement function overloading. For example, in C + +, the function void foo (int x, int y) is not the same as the symbol generated by the compilation of void foo (int x, float y), which is _foo_int_float.
Similarly, variables in C + + support class member variables and global variables in addition to local variables. The class member variable of the program that the user writes may have the same name as the global variable, and we use the "." to differentiate. In essence, the compiler, when compiling, is similar to the processing of the function and takes a unique name for the variable in the class, which differs from the name of the global variable named in the user program.
How to connect without extern "C" declaration
Assume that in C + +, the header file for module A is as follows:
Module a header file moduleA.h
#ifndef module_a_h
#define Module_a_h
int foo (int x, int y);
#endif

Reference the function in module B:
Module B implementation file ModuleB.cpp
#i nclude "ModuleA.h"
Foo (2,3);
In fact, during the connection phase, the connector looks for symbols like _foo_int_int from the target file Modulea.obj generated by module A!
add extern "C" after the declaration of the compilation and connection mode
After adding the extern "C" declaration, the header file of module a becomes:
Module a header file moduleA.h
#ifndef module_a_h
#define Module_a_h
extern "C" int foo (int x, int y);
#endif
Foo (2,3) is still called in the implementation file of Module B, and the result is:
(1) When module a compiles the target code of Foo, it does not have special handling of its name and adopts the C language method;
(2) When the connector looks for foo (2,3) call for the target code of Module B, it looks for the unmodified symbol name _foo.
If the function in module a declares Foo to be an extern "C" type, and Module B contains an extern int foo (int x, int y), module B cannot find the function in module A, and vice versa.
Therefore, it is possible to summarize the true purpose of the extern "C" statement in one sentence (the birth of any grammatical feature in any language is not arbitrary and is driven by demand from the real world.) When we're thinking about a problem, we can't just stay in the language, ask why it's doing it, what the motivation is, so we can understand a lot more in depth: Implementing a mixed programming of C + + and C and other languages.
Understanding of C + + in the establishment of extern "C" motivation, we are below to specifically analyze the extern "C" the usual use of skills:


The customary method of extern "C"

(1) in C + +, references to functions and variables in the C language, in the case of a C language header file (assuming cExample.h), the following processing is required:
extern "C"
{
#i nclude "CExample.h"
}
In the header file of the C language, only the extern type is specified for its external function, and the extern "C" declaration is not supported in the C language, and a compile syntax error occurs when the. c file contains the extern "C".
The C + + Reference Function Example project contains the following source code for the three files:
/* C Language header file: CExample.h */
#ifndef C_example_h
#define C_example_h
extern int Add (int x,int y);
#endif

/* C language Implementation file: CEXAMPLE.C */
#i nclude "CExample.h"
int add (int x, int y)
{
return x + y;
}

C + + implementation file, call Add:cppFile.cpp
extern "C"
{
#i nclude "CExample.h"
}
int main (int argc, char* argv[])
{
Add (2,3);
return 0;
}
If C + + calls a. dll written in C, the extern "C" {} should be added when the header file for the. dll is included or the interface function is declared.
(2) When referencing functions and variables in the C + + language, the header file of C + + must be added extern "C", but the header file that declares extern "C" cannot be directly referenced in C, only the extern "C" defined in C + + should be The function is declared as an extern type.
C reference C + + Function example the source code for the three files contained in the project is as follows:
C + + header file CppExample.h
#ifndef Cpp_example_h
#define Cpp_example_h
extern "C" int Add (int x, int y);
#endif

C + + implementation file CppExample.cpp
#i nclude "CppExample.h"
int add (int x, int y)
{
return x + y;
}
/* C Implementation file cfile.c
/* This compiles an error: #i nclude "cExample.h" */
extern int Add (int x, int y);
int main (int argc, char* argv[])
{
Add (2, 3);
return 0;
}




C-Function calls C + + functions

Example:
//Cpp.h
#ifndef __cpp_h__
#define __CPP_H__
class Class1 {
Class1 ();
~class1 ();
Public :
int I;
int J;
int Geti (void);
};
#endif
//End file


//cpp.cpp
#i nclude "stdafx.h"
#i nclude <iostream>
#i nclude "Cpp.h"
#i nclude "c.h"
using namespace std;//Open standard library namespace
Class1::class1 ()
{}
Class1::~class1 ()
{ }
int Class1::geti (void)
{
return i++;
}

//Compile the following function as called C
extern "C"
int get_class1_i (STRUCT1 * p)
{
Class1 * PClass1 = (class1 *) p;
cout << "C + +:" << Pclass1->geti () << Endl;
return Pclass1->geti ();
}
//End file

C.h
#ifndef __c_h__
#define __c_h__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int i; Consistent with variables in the Class1 class
Int J;
}struct1;
#ifdef __cplusplus
}
#endif
#endif
End file

C.c
#i nclude <cstdio>
#i nclude "C.h"
extern int get_class1_i (void * p);
Struct1 s;
int main (void)
{
printf ("C:%d\n", Get_class1_i (&s));
printf ("C:%d\n", Get_class1_i (&s));

return 0;
}
End file

Reference is made to the hybrid programming implementation in Ecos (http://sources.redhat.com/ecos/).
This example compiles in ads 1.2 and executes the results correctly.
VC + + When compiling, select the not using Precompile headers in the C.C file compilation option.


How to call C + + functions, in-class functions in C

In C, the question of how to call C + + functions, the simple answer is to use the extern "C" declaration of the function, when asked how to declare a member function within the class, a moment speechless, later on-line search, the Internet has a translation of C + + 's father's article can be used as a solution, then take mark.
The translated document Bjarne Stroustrup the original link address is http://www.research.att.com/~bs/bs_faq2.html#callCpp


Linux C calls C + + libraries
Transferred from: http://blog.linuxgem.org/tzc/show/551.html

Call C + + libraries, generally cannot be called directly, you need to convert C + + library to c interface output, you can use C call
Declare the C + + function as "extern" C "" (Make this declaration in your C + + code) and call it (in your C or C + + code). For example:
C + + code:
extern "C" void f (int);
void f (int i)
{
// ...
}

Then, you can use F () like this:
/* C Code: */
void f (int);
void cc (int i)
{
f (i);
/* ... */
}

Of course, this trick applies only to non-member functions. If you want to call member functions (including virtual functions) in C, you need to provide a simple wrapper (wrapper). For example:
C + + code:
Class C
{
// ...
Virtual double f (int);
};

extern "C" double Call_c_f (c* p, int i)//wrapper function
{
return p->f (i);
}

Then you can call C::f () like this:
/* C Code: */
Double call_c_f (struct c* p, int i);

void CCC (struct c* p, int i)
{
Double d = call_c_f (p,i);
/* ... */
}

If you want to call overloaded functions in C, you must provide a wrapper with a different name in order to be called by the C code. For example:
C + + code:
void f (int);
void f (double);

extern "C" void f_i (int i) {f (i);}
extern "C" void F_d (double D) {f (d);}

You can then use each of the overloaded F ():
/* C Code: */

void f_i (int);
void F_d (double);

void cccc (int i,double D)
{
F_i (i);
F_d (d);
/* ... */
}
Note that these techniques are also useful for calling C + + class libraries in c. Even if you cannot (or do not) modify C + + header files.

Let's look at the following example:
Aa.cxx
#include "Aa.h"
int Sample::method ()
{
cout<< "method is called!\n";
}
aa.h
#include <iostream>
using namespace Std;
Class sample
{
Public
int method ();
};
Generate a dynamic library libaa.so the above two files into the/usr/lib directory, compile the command as follows
sudo g++-fpic-shared-g-o/usr/lib/libaa.so aa.cxx-i.

Because the class is not recognized in C, the member functions of the above class are encapsulated into the C interface function output, which is encapsulated to convert the output interface to the C interface.
Mylib.cxx
#include "Add.h"
#ifndef _cplusplus
#define _cplusplus
#include "Mylib.h"
#endif

int MyFunc ()
{
Sample SS;
Ss.method ();
return 0;
}
Mylib.h
#ifdef _cplusplus
extern "C"
{
#endif

int MyFunc ();

#ifdef _cplusplus
}
#endif
Under Linux, the GCC compiler doesn't use variable _cplusplus to differentiate between C code or C + + code, and if you use the GCC compiler, here we can define a variable _cplusplus to differentiate between C and C + + code. Therefore, a variable _cplusplus is defined in Mylib.cxx to identify if "extern" C "is required to encapsulate the function interface into a C interface. However, if you use the g++ compiler you do not need to define _cplusplus specifically, the Compile command is as follows:
g++-fpic-shared-g-o mylib.so mylib.cxx-la-i.

MAIN.C
#include <stdio.h>
#include <dlfcn.h>
#include "Mylib.h"
Int
Main ()
{
Int (*dlfunc) ();
void *handle; Define a handle
Handle = Dlopen ("./mylib.so", rtld_lazy);//Get library handle
Dlfunc = Dlsym (handle, "MyFunc"); Get function entry
(*dlfunc) ();
Dlclose (handle);

return 0;
}
The compile command is as follows:
Gcc-o main main.c./MYLIB.SO-LDL
You can do it below.
It should be explained that because both MAIN.C and mylib.cxx need to contain mylib.h, and to encapsulate the function myfunc into the C interface function output requires "extern" C "", and C does not recognize "extern" C "", so you need to define _ Cplusplus to distinguish the function myfunc in Mylib.h.
It is also possible to invoke the MyFunc () function directly in the main function of MAIN.C, as described in the general method of calling library functions.

C + + and C language functions call each other


1. Introduction
The C + + language was originally created as "A better C", but this does not mean that C + + global variables and functions in C + + are compiled and connected in exactly the same way as C. As a language compatible with C, C + + retains some of the features of the procedural language (known as "not completely object-oriented"), so it can define global variables and functions that are not part of any class. However, after all, C + + is an object-oriented programming language, in order to support the overloading of functions, C + + to the global function of the processing method and C are obviously different.
2. Speaking from the standard header file
An enterprise has given the following interview questions:
Why does the standard header file have a structure similar to the following?
#ifndef __incvxworksh
#define __incvxworksh
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
} #endif #endif

Analysis
Obviously, the compiler macro "#ifndef __incvxworksh, #define __incvxworksh, #endif" in the header file prevents the header file from being repeatedly referenced.
So
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
What is the role of #endif?
3. Deep disclosure of extern "C"
extern "C" contains a double meaning, literally: First, the object it modifies is "extern", and secondly, the target it modifies is "C". Let's take a detailed reading of this twofold meaning.
The function or variable defined by extern "C" is of type extern;
extern is a keyword that indicates the scope (visibility) of functions and global variables in the C/s + + language, which tells the compiler that its declared functions and variables can be used in this module or in other modules. Remember, the following statement: extern int A;
is simply a declaration of a variable that does not define variable A and does not allocate memory space for a. Variable A can only be defined once in all modules as a global variable, or a connection error occurs.

Typically, the function and global variables that this module provides to other modules in the header file of the module are declared with the keyword extern. For example, if module B is to reference the global variables and functions defined in module A, only the header file of module A can be included. In this way, when a function in module A is called in Module B, in the compile phase, Module B cannot find the function, but it does not error; it will find this function in the target code generated from module a during the connection phase.
The keyword that corresponds to extern is static, and the global variables and functions it modifies can only be used in this module. Therefore, a function or variable may not be modified by extern "C" only if it is used by this module.
The variables and functions modified by extern "C" are compiled and concatenated in C language;

How to compile without extern "C" declaration
Let's start with a look at how C + + is compiled for a function that is similar to.
As an object-oriented language, C + + supports function overloading, whereas programming language C is not supported. Functions are compiled in C + + with different names in the symbol library than in the C language. For example, suppose a function is prototyped as: void foo (int x, int y);

The function is compiled by the C compiler in the symbol library with the name _foo, while the C + + compiler produces names like _foo_int_int (different compilers may generate different names, but all use the same mechanism, and the resulting new name is called "Mangled Name").
_foo_int_int such a name includes the function name, function parameter number and type information, C + + is this mechanism to implement function overloading. For example, in C + +, the function void foo (int x, int y) is not the same as the symbol generated by the compilation of void foo (int x, float y), which is _foo_int_float.
·
Similarly, variables in C + + support class member variables and global variables in addition to local variables. The class member variable of the program that the user writes may have the same name as the global variable, and we use the "." to differentiate. In essence, the compiler, when compiling, is similar to the processing of the function and takes a unique name for the variable in the class, which differs from the name of the global variable named in the user program.

How to connect without extern "C" declaration
Assume that in C + +, the header file for module A is as follows:
Module a header file moduleA.h
#ifndef module_a_h
#define Module_a_h
int foo (int x, int y); #endif
Reference the function in module B:
Module B implementation file ModuleB.cpp
#include "moduleA.h" foo (2,3);
In fact, during the connection phase, the connector looks for symbols like _foo_int_int from the target file Modulea.obj generated by module A!

add extern "C" after the declaration of the compilation and connection mode
After adding the extern "C" declaration, the header file of module a becomes:
Module a header file moduleA.h
#ifndef module_a_h
#define Module_a_h
extern "C" int foo (int x, int y);
#endif
Foo (2,3) is still called in the implementation file of Module B, and the result is:
(1) When module a compiles the target code of Foo, it does not have special handling of its name and adopts the C language method;
(2) When the connector looks for foo (2,3) call for the target code of Module B, it looks for the unmodified symbol name _foo.
If the function in module a declares Foo to be an extern "C" type, and Module B contains an extern int foo (int x, int y), module B cannot find the function in module A, and vice versa.
Therefore, it is possible to summarize the true purpose of the extern "C" statement in one sentence (the birth of any grammatical feature in any language is not arbitrary and is driven by demand from the real world.) When we're thinking about a problem, we can't just stay in the language, ask why it's doing it, what the motive is, so we can understand a lot more in depth:
Implement mixed programming of C + + and C and other languages.
Understand the C + + in the establishment of the extern "C" motivation, we are below to specifically analyze the extern "C" the usual use of skills.


4.extern "C" idiomatic method
(1) in C + +, references to functions and variables in the C language, in the case of a C language header file (assuming cExample.h), the following processing is required:
extern "C"
{
#include "cExample.h"
}
In the header file of the C language, only the extern type is specified for its external function, and the extern "C" declaration is not supported in the C language, and a compile syntax error occurs when the. c file contains the extern "C".
The author of C + + reference C Function Example project contains the source code of the three files as follows:

#ifndef C_example_h
#define C_example_h
extern int Add (int x,int y);
#endif
#include "cExample.h"
int add (int x, int y)
{
return x + y;
}
C + + implementation file, call Add:cppFile.cpp
extern "C"
{
#include "cExample.h"
}
int main (int argc, char* argv[])
{
Add (2,3);
return 0;
}
If C + + calls a. dll written in C, the extern "C" {} should be added when a header file that includes a. dll or an interface function is declared.
(2) When referencing functions and variables in the C + + language, the header file of C + + must be added extern "C", but the header file that declares extern "C" cannot be directly referenced in C, it should only be defined in C + + with extern "C" The function is declared as an extern type.
The author of the C-referenced function example of the three files in the project contains the following source code:
C + + header file CppExample.h
#ifndef Cpp_example_h
#define Cpp_example_h
extern "C" int Add (int x, int y);
#endif
C + + implementation file CppExample.cpp
#include "cppExample.h"
int add (int x, int y)
{
return x + y;
}

extern int Add (int x, int y);
int main (int argc, char* argv[])
{
Add (2, 3);
return 0;
}
An in-depth understanding of the role of the extern "C" in the compile and join phases described in section 3rd will give you a real understanding of the idioms described in this section from C + + to reference C functions and C. For the example code given in section 4th, you need to pay special attention to each detail.

C&c++--c function and C + + function calling each other problem

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.