[转]Linux下gcc编译生成动态链接库*.so文件并调用它

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。
1、动态库的编译

下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

//so_test.h:
#include “stdio.h”
void test_a();
void test_b();
void test_c();

//test_a.c:
#include “so_test.h”
void test_a()
{
 printf(“this is in test_a…\n”);
}

//test_b.c:
#include “so_test.h”
void test_b()
{
 printf(“this is in test_b…\n”);
}

//test_c.c:
#include “so_test.h”
void test_c()
{
 printf(“this is in test_c…\n”);
}
将这几个文件编译成一个动态库:libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

2、动态库的链接
在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。

test.c:
#include “so_test.h”
int main()
{
test_a();
test_b();
test_c();
return 0;
}
将test.c与动态库libtest.so链接生成执行文件test:
$ gcc test.c -L. -ltest -o test
测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
$ ldd test
执行test,可以看到它是如何调用动态库中的函数的。
3、编译参数解析
最主要的是GCC命令行的一个选项:
-shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

-L.:表示要连接的库在当前目录中

-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

4、注意

调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

在linux下可以用export命令来设置这个值,在linux终端下输入:
export LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:
然后再输入:export
即会显示是否设置正确
export方式在重启后失效,所以也可以用 vim /etc/bashrc ,修改其中的LD_LIBRARY_PATH变量。
例如:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/au1200_rm/build_tools/bin。

 

转自:http://blog.sina.com.cn/s/blog_54f82cc20101153x.html

[转]Linux下磁盘保留空间的调整,解决df看到的空间和实际磁盘大小不一致的问题

linux的硬盘分区程序会自动为root或指定的用户保留一定的磁盘空间默认是5%,在较大的分区或是不重要的分区上这种设置会占据过多不必要的空间, 利用mke2fs的-m reserved-percentage选项可以调整这个设置来获得更多的磁盘空间且不影响性能。而在创建了文件系统之后,用户可以用tune2fs来修 改这个设置比如tune2fs -m 1 /dev/sda4 可以将保留的空间设置为1%

看 mkfs.ext3 的man page,就可以知道原因了,其中有这么一句:
-m reserved-blocks-percentage Specify the percentage of the filesystem blocks reserved for the super-user. This avoids fragmentation, and allows root-owned daemons, such as syslogd(8), to continue to function correctly after non-privileged processes are prevented from writing to the filesystem. The default percentage is 5%.

也就是说,ext文件系统,包括ext2、ext3、ext4都会默认预留5%的磁盘空间,留给root用户维护系统或者记录系统关键日志的时候使用(比如磁盘使用空间已经100%的情况下的处理),这也就是导致普通用户无法使用部分磁盘空间的原因了。

如:

$ df -hl /dev/sda6
Filesystem Size Used Avail Use% Mounted on
/dev/sda6 42G 34G 5.8G 86% /linux/sda6

$ tune2fs -m 0 /dev/sda6
tune2fs 1.41.3 (12-Oct-2008)
Setting reserved blocks percentage to 0% (0 blocks)

$ df -hl /dev/sda6
Filesystem Size Used Avail Use% Mounted on
/dev/sda6 42G 34G 7.9G 81% /linux/sda6

另外一个具体操作过程如下,已经加了详细注释:

–之前的保留区有 732463 块

# tune2fs -l /dev/sda7 | grep "Reserved block count"
Reserved block count:     732463

–已用空间+可用空间 和 总空间 相比,还少了近3个G

# df
文件系统             1K-块      已用      可用 已用% 挂载点
/dev/sda7             57677500  47662588   7085060  88% /home

–调整:

# tune2fs -r 25600 /dev/sda7
tune2fs 1.41.9 (22-Aug-2009)
Setting reserved blocks count to 25600

–再来看看空间

# df
文件系统             1K-块      已用      可用 已用% 挂载点
/dev/sda7             57677500  47662584   9912516  83% /home

–确认调整成功

# sudo tune2fs -l /dev/sda7 | grep "Reserved block count"
Reserved block count:     25600

多了3G多的空间。而且还不是直接完全去掉保留区块,也留了百多兆以防不时之需。

转自: http://li2z.cn/2010/01/08/reserved_block/

Linux下使用Wget下载迅雷离线文件

为了避免会员共享离线下载的链接,迅雷离线下载时要通过cookie验证下载的合法性.wget里提供了载入cookies的方法。但是它所支持的cookies格式是类似于IE导出的cookies数据格式.如果你使用chrome浏览器,可以安装一个叫做edit this cookies的插件,来查找所需要的cookies值.

我们只需要找到gdriveid的值,再按照以下格式保存文件。

.vip.xunlei.com TRUE / FALSE 0 gdriveid B536D3D23A7EB11AC43348D41A132378
需要注意的是字段之间的分隔符是TAB

接下来,在迅雷的离线下载页面里,右键点击你要下载的文件有个,复制下载链接。连接很长,类似下面:

http://gdl.lixian.vip.xunlei.com/download?fid=0IJuQtRoa1UYXuy4PmsWuV8XrRoAoImCAAAAAKxLWWomgtV40ppw2jTWKkZ5BsNx&mid=666&threshold=150&tid=4AA706F5C4D097A6B95929DEFA23EA7B&srcid=4&verno=1&g=AC4B596A2682D578D29A70DA34D62A467906C371&scn=t5&i=E93B029C442F19024AA9EF8FB02AC90B&t=4&ui=517665&ti=240046314242&s=2190057472&m=0&n=01025FBB28696E646F1642BB2C65727665136E972B616E64611355BB3A6E74657211438D2C655F616E056E803E746163650F45812D5F776974096E972F325F7838576E8029645F7831541CD06E3034352E08428B5F00000000&ff=0&co=C6DD0FC61A4D9B3B673C9DF0CB0DA05B&cm=1

后只用wget加载cookie进行下载:

wget -c –load-cookies=”cookie文件” “下载地址” -O 文件重命名

执行命令,就开始正常下载文件。

其中,-c 代表支持断点续传,–load-cookies 加载cookie文件,-O 重命名文件.

例如:

wget -c –load-cookies=”1.c” “http://gdl.lixian.vip.xunlei.com/download?fid=0IJuQtRoa1UYXuy4PmsWuV8XrRoAoImCAAAAAKxLWWomgtV40ppw2jTWKkZ5BsNx&mid=666&threshold=150&tid=4AA706F5C4D097A6B95929DEFA23EA7B&srcid=4&verno=1&g=AC4B596A2682D578D29A70DA34D62A467906C371&scn=t5&i=E93B029C442F19024AA9EF8FB02AC90B&t=4&ui=517665&ti=240046314242&s=2190057472&m=0&n=01025FBB28696E646F1642BB2C65727665136E972B616E64611355BB3A6E74657211438D2C655F616E056E803E746163650F45812D5F776974096E972F325F7838576E8029645F7831541CD06E3034352E08428B5F00000000&ff=0&co=C6DD0FC61A4D9B3B673C9DF0CB0DA05B&cm=1” -O winxp.iso

因为下载链接非常长,会导致文件名过长不能下载的问题 所以需要自定义一个文件名。

在CentOS 6上安装Kdump

最近把扔在客厅的下载机从Ubuntu换成了centos,每天都会出现kernel panic,为了调试,我选择了Kdump来导出核心vmcore,在看了N多网上说的安装Kdump方法无果之后,果断GOOGLE搜索,终于找到一个可以用的方法。

一.安装kexec-tools

[root@CentOS ~]# yum install kexec-tools

二.添加 crashkernel=64M 在grub.conf中
vi /boot/grub/grub.conf

kernel /vmlinuz-2.6.32-279.14.1.el6.i686 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=VolGroup/lv_swap crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet crashkernel=64M

然后重启电脑,待重启后使用free -m会发现总内存比添加之前少了64M。

三.设置Kdump导出的vmcore保存位置。

[root@CentOS ~]# df
文件系统                 1K-块      已用      可用 已用% 挂载点
/dev/mapper/VolGroup-lv_root
                      51606140   1883516  47101184   4% /
tmpfs                   477572         0    477572   0% /dev/shm
/dev/sda1               495844     53469    416775  12% /boot
/dev/mapper/VolGroup-lv_home
                     1868714292 197403328 1576385756  12% /home

mkdir /var/crash
vi /etc/kdump.conf 添加

ext4 /dev/mapper/Volume00-var

四.启动Kdump服务。

[root@CentOS ~]# service kdump start
Starting kdump:                                            [确定]

五.测试Kdump运行

echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger

这时系统会马上panic,重启后检查/var/crash 会发现目录中有类似于127.0.0.1-2012-12-17-21:53:58目录生成,则代表Kdump运行正常。

参考:http://linuxczar.net/archives/383

【原创】Nginx Accesskey使用COOKIE作为KEY

网上有一篇文章是介绍使用COOKIE作为ACCESSKEY的KEY值的文章,以下是完整的方案:

NGINX 虚拟主机配置:

server
  {
    listen 80;
    server_name  www.yourdomian.com;
    root  /home/wwwroot/test;

if ( $http_cookie ~* " ng_cookie=(.+?)(?:;|$)")
{
    set $ng_cookie $1;
}

location /down/ {
  accesskey             on;
  accesskey_hashmethod  sha1;
  accesskey_arg         "token";
  accesskey_signature   "jzbk$ng_cookie";

}

location ~ .*\.(php|php5)?$ {
include php.conf;
        }

}

PHP部分:

0) $r.=$a{mt_rand(0,$l)}; 
   return $r; 
}
$key=code('32');//生成一个32位的随机值

$File='pure-ftpd'; //文件名

if(!isset($_COOKIE['ng_cookie'])) {
setcookie("ng_cookie",$key,time()+1800); //设置COOKIE有效期半小时
header("Refresh: 0"); //刷新页面
}

$token=sha1(jzbk.$_COOKIE['ng_cookie']); //KEY

echo '
'; echo "http://www.yourdomian.com/down/$File?token=$token"; //下载地址 echo '
'; echo $_COOKIE['ng_cookie']; ?>

FreeBSD开机自动同步时间。

最近把VPS系统换成了FreeBSD,发现每次重启之后时间都会不正确,使用以下的方法可以让FreeBSD在开机的时候自动使用NTP来校对时间。

编辑 /etc/rc.conf 加入以下代码:

ntpdate_enable="YES" # Run ntpdate to sync time on boot (or NO). 
ntpdate_program="ntpdate" # path to ntpdate, if you want a different one. 
ntpdate_flags="us.pool.ntp.org" # Flags to ntpdate (if enabled). 

NGINX下可用的WP super cache规则

最近把BLOG的缓存换成了WP super cache,但是这个插件默认是运行在APACHE下面的,根据各种度娘谷歌后找到了对应的NGINX下的规则。
1.简洁形:

location / {
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
}

2.完整形:

location / 
{ 

set $wp_super_cache_file ''; 
set $wp_super_cache_uri $request_uri;

if ( $request_method = POST ) 
{ 
set $wp_super_cache_uri ''; 
}

if ( $query_string ) 
{ 
set $wp_super_cache_uri ''; 
}

if ( $http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) 
{ 
set $wp_super_cache_uri ''; 
}

if ( $wp_super_cache_uri ~ ^(.+)$ ) 
{ 
set $wp_super_cache_file /wp-content/cache/wp_super_cache/$http_host/$1index.html; 
}

if ( -f $document_root$wp_super_cache_file ) 
{ 
rewrite ^(.*)$ $wp_super_cache_file break; 
}

if (-f $request_filename) 
{ 
expires 30d; 
break; 
}

if (!-e $request_filename) 
{ 
rewrite ^(.+)$ /index.php?q=$1 last; 
} 
}

说实话,对于这两种规则的区别不大搞得清,但是经测试都是可以用的,而且根据查看源码显示的都能正确读取到缓存,具体用哪一种就看自己的喜好了。