Linux hybrid programming + log4cpp

Source: Internet
Author: User

 

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!


 

 

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.