杂七杂八

1. 获取当前处理文件的文件名及行号,属于系统级全局变量:

__FILE__ && __LINE__


2. 宏的定义中 ##表示字符的连接符:

void Create##FuncName(){};


3. C++ 动态库编译示例

g++ DllCall.cpp -fpic -shared -g -o libDllCall.so
g++ Run.cpp -g -ldl -o Run

//DllCall.h头文件
#ifndef _DLL_CALL_
#define _DLL_CALL_
#ifdef WIN32
#ifdef DLLCALL_EXPORT
#define DLLCALL_API extern "C" _declspec(export)
#else
#define DLLCALL_API extern "C" _declspec(import)
#endif
#else
#define DLLCALL_API extern "C"
#endif
DLLCALL_API void test();
#endif

//DllCall.cpp
#include "DllCall.h"
#include <iostream>

DLLCALL_API void test() {
	std::cout << "Just test dynamic library ..." << std::endl;
}

/* 对于dlopen函数的打开模式,参见如下官方解释
* One of the following two values must be included in flag:
*
* RTLD_LAZY
*        Perform  lazy binding.  Only resolve symbols as the code that references them is executed.  If the symbol is never
*        referenced, then it is never resolved.  (Lazy binding is only performed for  function  references;  references  to
*        variables are always immediately bound when the library is loaded.)* 
* RTLD_NOW
*        If  this  value  is specified, or the environment variable LD_BIND_NOW is set to a non-empty string, all undefined
*        symbols in the library are resolved before dlopen() returns. If this cannot be done, an error is returned.
*
* Zero of more of the following values may also be ORed in flag:
*
* RTLD_GLOBAL
*        The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.* 
* RTLD_LOCAL
*        This  is  the  converse  of  RTLD_GLOBAL,  and  the default if neither flag is specified.  Symbols defined in this
*        library are not made available to resolve references in subsequently loaded libraries. 
* RTLD_NODELETE (since glibc 2.2)
*        Do not unload the library during dlclose().  Consequently, the library's static variables are not reinitialised if
*        the library is reloaded with dlopen() at a later time.  This flag is not specified in POSIX.1-2001. 
* RTLD_NOLOAD (since glibc 2.2)
*        Don't  load the library.  This can be used to test if the library is already resident (dlopen() returns NULL if it
*        is not, or the library's handle if it is resident).  This flag can also be used to promote the flags on a  library
*        that  is  already loaded.  For example, a library that was previously loaded with RTLD_LOCAL can be re-opened with
*        RTLD_NOLOAD | RTLD_GLOBAL.  This flag is not specified in POSIX.1-2001. 
* RTLD_DEEPBIND (since glibc 2.3.4)
*        Place the lookup scope of the symbols in this library ahead of the global scope.  This means that a self-contained
*        library  will  use  its own symbols in preference to global symbols with the same name contained in libraries that
*        have already been loaded.  This flag is not specified in POSIX.1-2001.
*/

//部分调用动态库函数代码
typedef void* (*FuncName)();

void* handle = dlopen("libDllCall.so", RTLD_LAZY);
if(handle == NULL) {
	std::cout << "Open Dynamic Library failed: " << dlerror() << std::endl;
	exit(1);
}

FuncName funcName = (FuncName)dlsym(handle, "test");
if(funcName == NULL) {
	std::cout << "Retrive func failed: " << dlerror() << std::endl;
	dlclose(handle);
	exit(1);
}
funcName();
dlclose(handle);

4. 处理程序的命令行参数

/*
* 关于getopt_long的用法, 如下参见其官方解释, 来至于man getopt_long
* The  getopt_long() function works like getopt() except that it also accepts long options, started out by two dashes.  (If
* the program accepts only long options, then optstring should be specified as an  empty  string  (""),  not  NULL.)   Long
* option  names  may  be  abbreviated  if  the abbreviation is unique or is an exact match for some defined option.  A long
* option may take a parameter, of the form --arg=param or --arg param.
* 
* longopts is a pointer to the first element of an array of struct option declared in <getopt.h> as
* 
*    struct option {
*        const char *name;
*        int has_arg;
*        int *flag;
*        int val;
*    };
* 
* The meanings of the different fields are:
* 
* name   is the name of the long option.
* 
* has_arg
*        is: no_argument (or 0) if the option does not take an argument; required_argument (or 1) if the option requires an
*        argument; or optional_argument (or 2) if the option takes an optional argument.
* 
* flag   specifies  how  results  are  returned  for a long option.  If flag is NULL, then getopt_long() returns val.  (For
*        example, the calling program may set val to the equivalent  short  option  character.)   Otherwise,  getopt_long()
*        returns  0,  and  flag  points to a variable which is set to val if the option is found, but left unchanged if the
*        option is not found.
* 
* val    is the value to return, or to load into the variable pointed to by flag.
* 
* The last element of the array has to be filled with zeroes.
* 
* If longindex is not NULL, it points to a variable which is set to the index of the long option relative to longopts.
*/

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <getopt.h>

#define cout std::cout
#define endl std::endl

const char* program_name;

void print_usage(FILE* stream, int exitcode) {
	fprintf(stream, "Usage: %s options [ inputfile ...]\n", program_name);
	fprintf(stream,
			"	-h	--help	Dispaly this usage information.\n"
			"	-o	--output filename	Write output to file.\n"
			"	-v	--verbose	Dispaly verbose information.\n");
	std::exit(exitcode);
}

int main(int argc, char **argv) {
	cout << "Hello World!!!" << endl;

	int next_option;

	const char* const short_options = "ho:v";
	const struct option long_options[] = {
			{"help",	0,	NULL,	'h'},
			{"output",	0,	NULL,	'o'},
			{"verbose",	0,	NULL,	'v'},
			{NULL,	0,	NULL,	0},
	};

	const char* output_filename = NULL;
	int verbose = 0;

	program_name = argv[0];

	do {
		next_option = getopt_long(argc, argv, short_options, long_options, NULL);
		switch (next_option) {
			case 'h':
				print_usage(stdout, 0);
			case 'o':
				output_filename = optarg;
				break;
			case 'v':
				verbose = 1;
				break;
			case '?':
				print_usage(stderr, 1);
			case -1:
				break;
			default:
				std::abort();
		}
	} while(next_option != -1);

	if(verbose) {
		int var;
		for (var = optind; var < argc; ++var) {
			printf("Argument: %s\n", argv[var]);
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值