Linux共享数据对象类似于windows中的动态链接库,其后缀通常为so.* (*为版本号),例如为我们所熟知的libpcap,它对应的文件为/usr/lib/libpcap.so。如果程序中使用了某共享数据对象文件,需要在链接时指定gcc的链接参数。如使用libpcap库时,加入lpcap;使用POSIX Thread时,加lpthread。原则就是当库文件为libname.so.*时,相应的链接参数为lname,当然,libname.so.*文件或其自身的符号链接需要放在/lib或者/usr/lib或者LIB_LIBRARY_PATH环境变量指定的路径下。
使用共享数据对象主要涉及一下四个函数:
void *dlopen(const char *filename, int flag); const char *dlerror(void); void *dlsym(void *handle, char *symbol); int dlclose(void *handle);
|
dlopen函数负责载入动态连接库文件,成功时返回动态链接库的句柄。flag参数为RTLD_LAZY时表示在执行动态链接库文件时解析未被决议的符号;为RTLD_NOW时表示在dlopen函数返回是解析未被决议的符号。dlsym函数根据动态链接库的句柄,返回名称为symbol的函数指针。dlerror返回asci形式的错误信息。dlclose负责将打开动态链接库的引用计数减一,仅当引用计数为0时,dlclose才执行关闭句柄操作,这意味着相同的动态链接库文件可以被打开多次。
下面给一段演示程序:
sort.h
#ifndef _SORT_H_ #define _SORT_H_ void bubble_sort(int[], int); #endif /* _SORT_H_ */
|
sort.c
#include "sort.h"
void bubble_sort(int elems[], int elem_count) { int tmp, i, j; for (i = 0; i < elem_count - 1; i++) for (j = 0; j < elem_count - i - 1; j++) if (elems[j+1] < elems[j]){ tmp = elems[j]; elems[j] = elems[j+1]; elems[j+1] = tmp; } }
|
test.c
#include <stdio.h> #include <dlfcn.h> #include "sort.h"
int main() { int items[] = {2, 5, 6, 1, -2, 6, 2, 10}; void (*sort)(int[], int); void *h; int i; h = dlopen("./libsort.so.1", RTLD_LAZY); if (!h){ fprintf(stderr, "Failed to load sort.so\n"); exit(-1); } sort = dlsym(h, "bubble_sort"); if (!sort){ fprintf(stderr, "Failed to export function bubble_sort\n"); exit(-1); } sort(items, sizeof(items) / sizeof(items[0])); for (i = 0; i < sizeof(items) / sizeof(items[0]); i++) fprintf(stdout, "%d\t", items[i]); fprintf(stdout, "\n");
dlclose(h); return 0; }
|
Makefile
CC=gcc CFLAG=-rdynamic -ldl TARGET_lIB_NAME=libsort.so.1 OBJECTS=libsort.so.1 *.o test
test: $(TARGET_lIB_NAME) test.o $(CC) $^ $(CFLAG) -o $@ libsort.so.1: sort.c $(CC) $< -shared -o $@ test.o: test.c $(CC) -c $<
.PHONY: clean clean: rm -rf $(OBJECTS)
|