2009年10月17日 星期六 20:44
转自:http://hi.baidu.com/plumstar/blog/item/fce3d1296138bef498250ab0.html
问题:在纯C环境下用TinyXML实现XML文件解析。方法是将其做成动态库,导出C接口。
首先来看个例子,参见http://blog.chinaunix.net/u/1574/showart_31971.html 第一阶段: //head.h class A { public: A(); virtual ~A(); int gt(); int pt(); private: int s; }; //firstso.cpp #include <iostream> #include "head.h" A::A{} A::~A{} int A::gt() { s = 10; } int A::pt() { std::cout << s << std::endl; } 编译命令:g++ -shared -o libmy.so firstso.cpp 这时候生成libmy.so文件,将其拷贝到系统库里面:/usr/lib (或将编译命令该为g++ -shared -o /usr/lib/libmy.so firstso.cpp,这样就无需拷贝了) 第二阶段:进行二次封装 //secso.cpp #include <iostream> #include "head.h" #ifndef _cplusplus #define _cplusplus #include "secso.h" #endif int f() { A a; a.gt(); a.pt(); return 0; } //secso.h #ifdef _cplusplus extern "C" { #endif int f(); #ifdef _cplusplus } #endif 编译命令:gcc -shared -o sec.so secso.cpp -L. -lmy 这时候生成第二个.so文件,此时库从一个类变成了一个C的接口,头文件里的_cplusplus用来识别是否需要“extern "C"”将函数接口封装成C接口 (注意:最后一个参数-lmy,-l表示库,my是libmy.so的略写,这也是动态和静态链接库的区别之一) 第三阶段:开始调用 //test.c #include <stdio.h> #include <dlfcn.h> int main() { void *handle; handle = dlopen("./sec.so", RTLD_LAZY); // 和库文件在一个目录下 int (*f)(); // 函数指针,(*f)前面是返回值,后面是参数 f = dlsym(handle, "f"); // 注意名字的一致性,"f"和生成第二个库头文件里的一致 int result = f(); // 若有参数,加上即可 return 0; } 编译命令:gcc -rdynamic -s test.c -ldl 生成a.out,运行即可 总结:将其运用到TinyXML,要对所用到的方法做一个C的接口,不同的是int (*f)();这个函数指针可能会很复杂,返回值和参数。 另外,还遇到一个还未解决的问题,先调用库(第二个库)里的一个函数,返回一个指针,再调用库里的另一个函数,以这个指针为参数,这时指针的地址是一样的,但是所指的内容就不一样了,这就在对象的传递上遇到了麻烦。 望高手不吝赐教。 |