mingw编译log4c

1, 在mingw中配置log4c

configure --disable-doc --enable-reread --without-expat --prefix=`pwd`/dest && make -j && make install


小插曲:杀毒软件等,360,qq等,可能会把configure时候产生的conftest.exe误报为病毒,导致configure失败。

2, 在examples文件夹中创建用于封装log4c的l4c源文件


/*
* This is one of log4c example programs.
*
* Notice how no relationships between the category and a certain
* priority, appender, or formatter are coded here.  These are all left
* to the log4crc config file so they can be chaned without recompiling
* 
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#ifndef _WIN32
#include <sys/time.h>
#else
#include <time.h>
#include <windows.h>
#include <winsock.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "log4c.h" // 引用package自带的头文件

#define L4C_API __declspec(dllexport)

L4C_API 
int l4c_init(void){
	return log4c_init();
}

L4C_API 
void * l4c_category_get(const char* a_name){
	return log4c_category_get(a_name);
}

L4C_API 
void l4c_category_log(const void * a_category
						, int a_priority
						, const char* a_format, ...){
    if (log4c_category_is_priority_enabled((log4c_category_t*)a_category
											, a_priority)) 
	{
		va_list va;
		va_start(va, a_format);
		log4c_category_vlog(a_category, a_priority, a_format, va);
		va_end(va);
    }
}

L4C_API 
int l4c_fini(void){
	return log4c_fini();
}


3, 编译生成l4c动态链接库

gcc -o l4c.dll -fPIC -shared -static -O0 -g -w -I../dest/include  l4c.c ../dest/lib/liblog4c.a



4, 使用Dependency Walker查看自定义函数的ordinal



也可以用dumpbin查看自定义函数在dll中位置

dumpbin /exports l4c.dll

Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file l4c.dll

File Type: DLL

  Section contains the following exports for l4c.dll

    00000000 characteristics
    52245CBA time date stamp Mon Sep 02 17:39:06 2013
        0.00 version
           1 ordinal base
           4 number of functions
           4 number of names

    ordinal hint RVA      name

          1    0 0000158B l4c_category_get
          2    1 0000159E l4c_category_log
          3    2 000015DE l4c_fini
          4    3 0000157E l4c_init

  Summary

        1000 .CRT
        2000 .bss
        1000 .data
        5000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
       18000 .debug_info
        5000 .debug_line
       11000 .debug_loc
        1000 .debug_pubnames
        1000 .debug_pubtypes
        1000 .debug_ranges
        1000 .debug_str
        1000 .edata
        3000 .eh_frame
        1000 .idata
        A000 .rdata
        1000 .reloc
        C000 .text
        1000 .tls

5,制作def文件

LIBRARY	"l4c"
DESCRIPTION "simple wrapper of l4c"
EXPORTS
    l4c_category_get	        @1
    l4c_category_log            @2
    l4c_fini                    @3
    l4c_init                    @4

6,生成lib

lib /def:l4c.def /out:l4c.lib /machine:x86

在msvc的命令行里可以执行dumpbin和lib等vc++ sdk的工具

7,制作一个简单的头文件


#ifndef _L4C_WIN32_H_
#define _L4C_WIN32_H_

#ifdef WIN32
#ifdef L4C_EXPORTS
#    define L4C_API       __declspec(dllexport)
#else
#    define L4C_API       __declspec(dllimport)
#endif
#else
#    define L4C_API       
#endif

enum log4c_priority_level_t{
    /** fatal */    LOG4C_PRIORITY_FATAL    = 000, 
    /** alert */    LOG4C_PRIORITY_ALERT    = 100, 
    /** crit */     LOG4C_PRIORITY_CRIT     = 200, 
    /** error */    LOG4C_PRIORITY_ERROR    = 300, 
    /** warn */     LOG4C_PRIORITY_WARN     = 400, 
    /** notice */   LOG4C_PRIORITY_NOTICE   = 500, 
    /** info */     LOG4C_PRIORITY_INFO     = 600, 
    /** debug */    LOG4C_PRIORITY_DEBUG    = 700,
    /** trace */    LOG4C_PRIORITY_TRACE    = 800,
    /** notset */   LOG4C_PRIORITY_NOTSET   = 900,
    /** unknown */  LOG4C_PRIORITY_UNKNOWN  = 1000
} ;

#ifdef __cplusplus
extern "C" {
#endif

	L4C_API int l4c_init(void);

	L4C_API void * l4c_category_get(const char* a_name);

	L4C_API void l4c_category_log(const void * a_category
					, int a_priority
					, const char* a_format,...);

	L4C_API int l4c_fini(void);

#ifdef __cplusplus
};
#endif

#endif


8, 测试代码

#include "l4c.h"
#pragma comment(lib, "l4c.lib")

int main(int argc, char** argv)
{
  int i = 0;
  void* mycat = (void*)0;
  l4c_init();
  mycat = l4c_category_get("six13log.log.app.application2");
  for (i = 0; i < 100; i++)
	l4c_category_log(mycat, LOG4C_PRIORITY_DEBUG, "Debugging app 2");
  l4c_fini();
  return 0;
}


9, 测试用的配置文件log4crc

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE log4c SYSTEM "">

<log4c version="1.2.3">
    <config>
        <bufsize>0</bufsize>
        <debug level="2"/>
        <nocleanup>0</nocleanup>
        <reread>1</reread>
    </config>

    <category name="root" priority="notice"/>
    <category name="six13log.log" priority="error" appender="stdout" />
    <rollingpolicy name="myrollingpolicy" type="sizewin" maxsize="1024" maxnum="10" />
    <appender name="myrollingfileappender" type="rollingfile" logdir="." prefix="myprefix" layout="dated" rollingpolicy="myrollingpolicy" />
    <appender name="stdout" type="stream" layout="basic"/>
    <appender name="stderr" type="stream" layout="dated"/>
    <appender name="syslog" type="syslog" layout="basic"/>
    <appender name="s13file" type="s13_file" layout="basic"/>
    <appender name="plain_stderr" type="s13_stderr" layout="none"/>
    <appender name="cat_stderr" type="s13_stderr" layout="catlayout"/>
    <appender name="xml_stderr" type="s13_stderr" layout="xmllayout"/>
    <appender name="user_stderr" type="s13_stderr" layout="userlayout"/>
    <layout name="basic" type="basic"/>
    <layout name="dated" type="dated"/>
    <layout name="catlayout" type="s13_cat"/>
    <layout name="xmllayout" type="s13_xml"/>
    <layout name="none" type="s13_none"/>
    <layout name="userlayout" type="s13_userloc"/>
    <category name="six13log.log.app.application2" priority="debug" appender="cat_stderr" />
    <category name="six13log.log.app.application3" priority="debug" appender="user_stderr" />
    <category name="six13log.log.app" priority="debug" appender="myrollingfileappender" />
</log4c>


10, 编译测试代码

cl dlltest.c

11, 运行测试代码

H:\log4c-1.2.3\examples\dlltest>dlltest.exe
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2
[stdout] DEBUG    six13log.log.app.application2 - Debugging app 2

12, 截图



注意:

1) 多个appender 不能共享一个policy,否则,只有一个工作,一定要为每一个appender创建一个policy。

2)log4c的性能不高,如果应用在数据处理的逻辑里面非常不合适,一些GUI程序可能比较合适,主要的一个性能瓶颈在log4c_category_log, 大概一毫秒也就是6条左右的速度。 然而我用fprintf直接刷到文件的速度比这个要快至少500倍以上,16ms打印了9000条左右。

一小段测试用的bench对比,log4c_category_log vs. fprintf

/*
* This is one of log4c example programs.
*
* Notice how no relationships between the category and a certain
* priority, appender, or formatter are coded here.  These are all left
* to the log4crc config file so they can be chaned without recompiling
* 
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef _WIN32
#include <sys/time.h>
#else
#include <time.h>
#include <windows.h>
#include <winsock.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "log4c.h"

#ifdef _WIN32
#if !defined(__MINGW32__) && !defined(__MINGW64__)
int gettimeofday(struct timeval* tp, void* tzp) {
  DWORD t;
  t = timeGetTime();
  tp->tv_sec = t / 1000;
  tp->tv_usec = t % 1000;
  /* 0 indicates that the call succeeded. */
  return 0;
}
#endif

#if !defined(HAVE_SLEEP) || !HAVE_DECL_SLEEP
#define sleep(x) Sleep(x*1000)
#endif

#endif /* _WIN32 */

#include "log4tvu.h"

#include <map>
#include <string>
typedef unsigned int uint32;
#include <list>
#include <TvuMutex.hpp>
#include <TvuSemaphore.hpp>
#include <TvuThread.hpp>
#include <FIFO.hpp>

enum {
	MaxLogCount = 20,
	MaxLogLength= 1000,
	MaxLogCache = 20000,
};

struct logstruct {
	int level;
	char cat[20];
	char msg[200];
};

static FIFO<void * > * s_log = NULL;

void * backlog(void *args)
{
  static bool initialized = false;
  static std::map<std::string, log4c_category_t *> catcache;

  log4c_category_t* mycat = NULL;
  if (!initialized) {
	log4c_init();
	initialized = true;
  }
  
  static char * logblock = NULL;
  static int logcount = 0;
  
  FILE * fout = fopen("1.log", "w");
  
  while(true)
  {
	if (logcount >= MaxLogCache){
		logcount = 0;
		free(logblock);logblock = NULL;
	}

	if (logblock == NULL){
		s_log->Pick((void **)&logblock, INFINITE);
		logcount = 0;
	}
	
	logstruct s;
	memcpy(&s, logblock + logcount * sizeof(logstruct), sizeof(logstruct));
	logcount ++;
	
	/*	*/
	if (catcache.find(s.cat) == catcache.end())
	{
		mycat = log4c_category_get(s.cat);
		catcache [s.cat] = mycat;
	}else{
		mycat = catcache [s.cat];
	}

	//log4c_category_log(mycat, s.level, s.msg);
	fprintf(fout, "%d, %s\n", GetTickCount(), s.msg);
  }      
}

int tvulog(int level, const char * cat, const char * format, ...)
{
  if (s_log == NULL){
	s_log = new FIFO<void *>(MaxLogCount);
  }
  
  static bool backlogrunning = false;
  if (!backlogrunning){
	CTvuThread t;
	t.Create(backlog, NULL);
	backlogrunning = true;
  }
  
  int cursize = s_log->GetSize();
  char logstr [MaxLogLength] = "";
  sprintf(logstr, "the CUrrent q size is %d", cursize);
  
  // 1Mega per block.
  logstruct s; s.level = level;
  strcpy(s.cat, cat);
  strcpy(s.msg, logstr);
  
  static char * logblock = NULL;
  static int logcount = 0;
  
  if (logcount >= MaxLogCache){
	s_log->Push(logblock, INFINITE);
	logcount = 0;
	logblock = NULL;
  }
  
  if (logblock == NULL){
	logblock = (char*)malloc(sizeof(logstruct) * MaxLogCache);
  }
  
  memcpy(logblock + sizeof(logstruct) * logcount, &s, sizeof(logstruct));
  logcount ++;
    
  return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值