Because the log4cpp library is used, and there are very few log4c materials, I am too lazy to study its usage, so I decided to try the mixed programmer.
First, first reference the C ++ it Father: stroustrup an article "C ++ style and technique FAQ" (http://www2.research.att.com /~ A small segment in BS/bs_faq2.html:
Just declare the C function '''extern "C" ''(in your c ++ code) and call it (from your C or C ++ Code). For example:
// C++ codeextern "C" void f(int);// one wayextern "C" {// another wayint g(double);double h();};void code(int i, double d){f(i);int ii = g(d);double dd = h();// ...}
The definitions of the functions may look like this:
/* C code: */void f(int i){/* ... */}int g(double d){/* ... */}double h(){/* ... */}
Note that C ++ type rules, not C Rules, are used. so you can't call function declared ''extern" C "'' with the wrong number of argument. for example:
// C++ codevoid more_code(int i, double d){double dd = h(i,d);// error: unexpected arguments// ...}
Just declare the C ++ function '''extern "C" ''(in your c ++ code) and call it (from your C or C ++ Code). For example:
// C++ code:extern "C" void f(int);void f(int i){// ...}
Now F () can be used like this:
/* C code: */void f(int);void cc(int i){f(i);/* ... */}
Naturally, this works only for non-member functions. If you want to call member functions (incl. virtual functions) from C, you need to provide a simple 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);}
Now C: F () can be used 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 from C, you must provide wrappers with distinct names for the C code to use. 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); }
Now the F () functions can be used like this:
/* 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 can be used to call a C ++ library from C code even if you cannot (or do not want to) modify the C ++ headers.
Since we use C to call C ++, we do not care about C ++ to call C. As we can see above, it is troublesome to call C ++ class member functions. So I wrote a function to encapsulate the class.
Because the call logs of log4cpp are troublesome, unlike log4j, a lot of things need to be initialized every time, So we encapsulate these things into a class of log4cppbase:
Here is code:
Log4cppbase. h
# Ifndef log4cppbase_h <br/> # define log4cppbase_h <br/> # include <iostream> <br/> # include "log4cpp/category. HH "<br/> # include" log4cpp/propertyconfigurator. HH "<br/> # include <stdarg. h> <br/>/* <br/> * Author: lan Zhihong from xmu soft <br/> */<br/> class log4cppbase <br/> {<br/> protected: <br/> log4cppbase () <br/>{< br/> try {<br/> log4cpp: propertyconfigurator: Configure ("log4cpp/log4cpp. conf "); <br/>} Cat CH (log4cpp: configurefailure & F) <br/>{< br/> STD: cout <"Configure problem" <F. what () <STD: Endl; <br/>}< br/> iroot = & log4cpp: Category: getroot (); <br/> isub = & log4cpp: Category: getinstance (STD: string ("sub1"); </P> <p >}< br/> PRIVATE: <br/> log4cppbase & operator = (log4cppbase &); <br/> log4cppbase (const log4cppbase &); </P> <p> Public: <br/> ~ Log4cppbase (); <br/> static log4cppbase * getinstance (); <br/> static STD: String vform (const char * format, va_list ARGs ); <br/> void Info (const STD: string & MSG); <br/> void debug (const STD: string & MSG ); <br/> void notice (const STD: string & MSG); <br/> void warn (const STD: string & MSG ); <br/> void error (const STD: string & MSG); <br/> void CRIT (const STD: string & MSG ); <br/> void alert (const STD: string & MSG); <br/> void emerg (const STD: string & MSG ); <br/> void fatal (const STD: string & MSG); <br/> PRIVATE: <br/> static log4cppbase * iinstance; <br/> log4cpp :: CATEGORY * isub; <br/> log4cpp: category * iroot; <br/>}; <br/> # endif
Log4cppbase. cpp
# Include "log4cppbase. H "<br/> # include <sstream> <br/> # include <stdio. h> <br/> # define vsnprintf </P> <p> log4cppbase * log4cppbase: iinstance = 0; <br/> log4cppbase ::~ Log4cppbase () <br/>{< br/> If (isub! = NULL) <br/>{< br/> Delete isub; <br/> isub = NULL; <br/>}< br/> If (iroot! = NULL) <br/>{< br/> Delete iroot; <br/> iroot = NULL; <br/>}< br/> If (iinstance! = NULL) <br/>{< br/> Delete iinstance; <br/> iinstance = NULL; <br/>}< br/> log4cppbase * log4cppbase: getinstance () <br/>{< br/> If (iinstance = 0) <br/> iinstance = new log4cppbase (); <br/> return iinstance; <br/>}< br/> STD: String log4cppbase :: vform (const char * format, va_list ARGs) <br/>{< br/> size_t size = 1024; <br/> char * buffer = new char [size]; </P> <p> while (1) {<br/> int n = vsnprintf (Buf Fer, size, format, argS); </P> <p> // if that worked, return a string. <br/> If (n>-1) & (static_cast <size_t> (n) <size) {<br/> STD: String S (buffer ); <br/> Delete [] buffer; <br/> return s; <br/>}</P> <p> // else try again with more space. <br/> size = (n>-1 )? <Br/> N + 1: // ISO/IEC 9899: 1999 <br/> size * 2; // twice the old size </P> <p> Delete [] buffer; <br/> buffer = new char [size]; <br/>}< br/> void log4cppbase: Info (const STD: string & MSG) <br/>{< br/> isub-> Info (MSG); <br/>/* <br/> va_list Va; <br/> va_start (va, MSG); <br/> isub-> Info (vform (MSG, VA); <br/> va_end (VA ); <br/> */<br/>}< br/> void log4cppbase: Debug (const STD: string & MSG) <br/>{< br/> isub-> Info (MSG); <br/>}< br/> void log4cppbase: Notice (const STD: string & MSG) <br/>{< br/> isub-> notice (MSG); <br/>}< br/> void log4cppbase: Warn (const STD: string & MSG) <br/>{< br/> isub-> warn (MSG); <br/>}< br/> void log4cppbase: Error (const STD: string & MSG) <br/>{< br/> isub-> error (MSG); <br/>}< br/> void log4cppbase: CRIT (const STD: string & MSG) <br/>{< br/> isub-> CRIT (MSG); <br/>}< br/> void log4cppbase: Alert (const STD: string & MSG) <br/>{< br/> isub-> alert (MSG); <br/>}< br/> void log4cppbase: emerg (const STD: string & MSG) <br/>{< br/> isub-> emerg (MSG); <br/>}< br/> void log4cppbase: Fatal (const STD: string & MSG) <br/>{< br/> isub-> fatal (MSG); <br/>}< br/>/* <br/> int main (INT argc, char ** argv) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> int I = 5; <br/> instance-> Info ("Hello World"); <br/> return 0; <br/>}< br/> */
Because a non-member function called C ++ is selected, such a class log4cpputil is added.
Here is code:
Log4cpputil. h
# Ifdef _ cplusplus <br/> extern "C" <br/>{< br/> # endif <br/> void log4cpp_info (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_debug (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_notice (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_warn (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_error (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_crit (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_alert (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_emerg (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/> # ifdef _ cplusplus <br/> extern "C" <br/> {<br/> # endif <br/> void log4cpp_fatal (const char * MSG ,...); <br/> # ifdef _ cplusplus <br/>}< br/> # endif <br/>
Log4cpputil. cpp
# Ifndef _ cplusplus <br/> # DEFINE _ cplusplus <br/> # endif <br/> # include "log4cppbase. H "<br/> # include" log4cpputil. H "</P> <p> void log4cpp_info (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> Info (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_debug (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> debug (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_notice (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> notice (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_warn (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> warn (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_error (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> error (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_crit (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> CRIT (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_alert (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> alert (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_emerg (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> emerg (instance-> vform (MSG, VA); <br/> va_end (VA ); <br/>}< br/> void log4cpp_fatal (const char * MSG ,...) <br/>{< br/> log4cppbase * instance = log4cppbase: getinstance (); <br/> va_list Va; <br/> va_start (va, MSG ); <br/> instance-> fatal (instance-> vform (MSG, VA); <br/> va_end (VA); <br/>}
Then, call log4cpputil in your own C code. The test code I use is as follows:
# Include <stdio. h> <br/> # include "log4cpputil. H "<br/> extern void log4cpp_info (const char * MSG ,...); <br/> extern void log4cpp_debug (const char * MSG ,...); <br/> extern void log4cpp_notice (const char * MSG ,...); <br/> extern void log4cpp_warn (const char * MSG ,...); <br/> extern void log4cpp_error (const char * MSG ,...); <br/> extern void log4cpp_crit (const char * MSG ,...); <br/> extern void log4cpp_alert (const char * MSG ,...); <br/> extern void log4cpp_emerg (const char * MSG ,...); <br/> extern void log4cpp_fatal (const char * MSG ,...); </P> <p> int main () <br/> {<br/> int I = 3; <br/> log4cpp_info ("Hello: % d ", i); <br/> log4cpp_debug ("Hello: % d", I); <br/> log4cpp_notice ("Hello: % d", I ); <br/> log4cpp_warn ("Hello: % d", I); <br/> log4cpp_error ("Hello: % d", I ); <br/> log4cpp_crit ("Hello: % d", I); <br/> log4cpp_alert ("Hello: % d", I ); <br/> log4cpp_emerg ("Hello: % d", I); <br/> log4cpp_fatal ("Hello: % d", I); <br/> return 0; <br/>}
In C code, use extern to tell the compiler that this function is stored in other files.
Compile the command line in Linux as follows:
1. Compile log4cppbase. Because I have installed the log4cpp library on the local machine to/use/lib, you can directly compile log4cppbase based on the following code without the path of the top library.
G ++-FPIC-llog4cpp-shared-g-o liblog4cppbase. So log4cppbase. cpp
2. Compile log4cpputil. Because log4cpputil requires log4cppbase, you need to set the search path of the top Library to the current path ./
G ++-FPIC-shared-g-o liblog4cpputil. So log4cpputil. cpp-I ./
3. compile your own test. C to generate an executable file. Here, you need to add all the two library files compiled above to compile them into an executable file.
Gcc-O test. C./liblog4cpputil. So./liblog4cppbase. So
Compiled successfully! Enjoy your chicken leg at night!
The above is the compilation on PC
The above method does not work if the cross-compilation is performed on the board, because the system cannot find the log4cpp library or other libraries, you can refer to the previous article "[development tools] GCC command line details", which I have reproduced, and I cross-compiled log4cpp to/use/local, and my own/usr below also has a PC version of log4cpp, so pay attention to which command to call, so use absolute path/usr/local/bin/log4cpp-config
Modify the command again as follows:
Arm-Linux-G ++-FPIC-shared '/usr/local/bin/log4cpp-config -- Libs -- cflags'-O liblog4cppbase. So log4cppbase. cpp
Arm-Linux-G ++-FPIC-shared '/usr/local/bin/log4cpp-config -- Libs -- cflags'-O liblog4cpputil. So log4cpputil. cpp-I ./
Arm-Linux-GCC '/usr/local/bin/log4cpp-config -- Libs -- cflags'-O test. c log4cpp/liblog4cppbase. So log4cpp/liblog4cpputil. So
Compiled successfully, transplanted to the Development Board, and ran successfully!