[NOTE] Windows&Linux动态链接库学习笔记

来源:互联网 发布:写网页的软件 编辑:程序博客网 时间:2024/05/20 09:44

Windows&Linux动态链接库学习笔记

-- By Water

       在一个开发项目中需要用到有着统一标准的接口,但是内部实际功能却各不相同的动态链接库的开发,并要在Window和Linux中去分别实现显示调用。

       基于这个需求学习了解一下相关动态库的知识,以下是相关的学习笔记。
       动态链接库在Windows里面叫做“Dynamic Link Library”简称 “DLL”,因此Window里面一般动态链接库文件后缀也就是dll。在Linux里面类似Windows动态链接库的叫做“Shared Object” (共享对象),在Linux系统下动态库文件名的后缀就是“so”。
       接下来将学习一些简单的Window & Linux 平台下 dll & so的创建和使用方法。先从最熟悉的Windows + MSVC开始学习实验。
       由于个人工作环境基本都是C语言,下面测试用的代码都是C语言为基础的代码,C++以及其他语言创建dll的差别这里不做研究。

Windows + msvc dll的创建和使用实验

我使用的是msvc++ 6.0,最新的版本应该是类似的方法。
实验步骤如下:

1. 先建立一个“dll_note”的WorkSpace以便将来便于工程管理


2. 在WorkSpace上创建“hello_dll”的project


创建一个空的dll工程。


3. 在WorkSpace上建立一个“dll_demo”的控制台dll测试程序



4. 在“hell_dll”中增加测试代码文件“hello_dll.h”和“hello_dll.c”

代码如下:

hello_dll.h

<span style="font-family:Microsoft YaHei;font-size:18px;">#ifndef __hello_h_#define __hello_h_#ifdef __cplusplusextern "C" {#endifvoid hello_dll(void);#ifdef __cplusplus}#endif#endif /* #ifndef __hello_h_ */</span>


hello_dll.c

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <stdio.h>#include "hello_dll.h"void hello_dll(void){printf("hello dll\n");}</span>

hello_dll  的代码很简单,就是一个hello_dll的函数,打印了“hello dll”字符串。


5. 在“dll_demo”project中添加测试代码文件“dll_demo.c”

代码如下: dll_demo.c

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <stdio.h>#include <wtypes.h>#include <winbase.h>#include <winerror.h>typedef void (*fp_hello_dll)(void);void main(void){HMODULE h_dll;DWORD error_code;fp_hello_dll hello_dll;printf("start load library\n");h_dll = LoadLibrary("hello_dll.dll");if (h_dll) {printf("get function entry from dll by symbol name\n");hello_dll = (fp_hello_dll)GetProcAddress(h_dll, "hello_dll");if (hello_dll) {hello_dll();} else {error_code = GetLastError();printf("can't get valid function entry, error code: %d\n", error_code);}FreeLibrary(h_dll);} else {error_code = GetLastError();printf("load library fail, error code: %d\n", error_code);}printf("\n__end__\n");}</span>


测试代码中主要用到了下面4个函数:“LoadLibrary”加载dll,“GetProcAddress”获取dll中对应Symbol的函数入口地址,“FreeLibrary”卸载dll,和“GetLastError”可以获得最后出错的代码便于出错分析。

6. 编译、运行、debu

分别编译“hello_dll”和“dll_demo”两个project,会发现都能编译过。

但运行“dll_demo”的时候出现如下出错信息:


<span style="font-family:Microsoft YaHei;font-size:18px;">start load libraryload library fail, error code: 126</span>


到<winerror.h>中查找126出错代码有如下描述:

<span style="font-family:Microsoft YaHei;font-size:18px;">// MessageId: ERROR_MOD_NOT_FOUND// MessageText://  The specified module could not be found.#define ERROR_MOD_NOT_FOUND              126L</span>
 

实际上就是Windows程序调用LoadLibrary的时候找不到“hello_dll.dll”这个dll文件。

编译的时候产生的dll在“hello_dll”project 的Debug或者Release目录下面。

但Window在找dll的时候并不包含这个路径,Window搜索dll路径的优先级如下:

1. 当前程序运行的目录

2. Window目录

3. System目录

4. 环境变量PATH中罗列的所有目录

为了方便,将“hello_dll”Project 的Debug或Release目录下的“hello_dll.dll”文件拷贝到“dll_demo”Project目录下。

 

再运行“dll_demo”,仍然出现错误,信息如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">start load libraryget function entry from dll by symbol namecan't get valid function entry, error code: 127</span>
 

对应的127出错代码描述如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">// MessageId: ERROR_PROC_NOT_FOUND// MessageText://  The specified procedure could not be found.#define ERROR_PROC_NOT_FOUND             127L</span>

出错的意思是找不到“hello_dll”这个Symbol对应的函数入口地址。查了一下资料,原来Windows不同于Linux,dll需要export的函数需要添加修饰符:_declspec(dllexport)

修改后的“hello_dll.h”如下:

_declspec(dllexport) void hello_dll(void);

重新编译“hello_dll”后拷贝dll到“dll_demo”目录下再运行“dll_demo”结果如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">start load libraryget function entry from dll by symbol namehello dll</span>
这样的结果就符合预期了。

7. Windows + msvc dll小结

a) 需要export的函数要在头文件中对应的函数前添加修饰符:_declspec(dllexport)

b) 使用dll的代码需要添加<wtypes.h>和<winbase.h>两个头文件。

c) 使用前调用LoadLibrary加载dll

d) 使用GetProcAddress获得对应函数的函数入口

e) 如果遇到错误可以使用GetLastError获得出错的原因

f) 使用完毕调用FreeLibrary释放dll

8. 一些不足的改进

上面的例子发现一些不太爽的地方:

1. 每次修改编译完“hello_dll”都要拷贝一下hello_dll.dll

2. 使用dll的symbol对应的函数不是那么直观

为了解决这些问题,对msvc设定以及代码做了如下修改:

A) 在“dll_none”WorkSpace目录下创建“inc”、“lib”、“src”几个目录。

B) 把“hello_dll.h”和“hello_dll.c”、“dll_demo.c”文件分别从“hello_dll”&“dll_demo”Project转移到“inc”和“src”目录

C) 修改“hello_dll.h”代码如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">#ifndef __hello_h_#define __hello_h_#ifdef __cplusplusextern "C" {#endif#ifdef BUILD_DLL_declspec(dllexport) void hello_dll(void);#elsevoid (*hello_dll)(void);#endif#ifdef __cplusplus}#endif#endif /* #ifndef __hello_h_ */</span>

这样build dll和引用dll可以使用同一份头文件,只需要在build dll的时候加上“BUILD_DLL”的config即可。

D) 对应的修改“hello_dll”Project 配置

增加BUILD_DLL definition。

增加include路径“..\inc”,使得“hello_dll”Project可以找到“hello_dll.h”这个头文件。

修改Debug版的dll输出到..\lib\hello_dll_d.dll

修改Release版的dll输出到“..\lib\hello_dll.dll”

这样就能让debug & release版本的dll都输出到lib目录下以便其他程序使用。

 

E) 修改“dll_demo”Project的Include设置

这样“dll_demo”Project就能与“hello_dll”访问同一个“hello_dll.h”头文件了。

F) 修改“dll_demo.c”部分代码如下

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <stdio.h>#include <wtypes.h>#include <winbase.h>#include <winerror.h>#include "hello_dll.h"void main(int argc, char **argv){HMODULE h_dll;DWORD error_code;if (argc < 2) {printf("cmd fmt: <dll path>\n");return;}printf("start load library\n");h_dll = LoadLibrary(argv[1]);if (h_dll) {printf("get function entry from dll by symbol name\n");hello_dll = (void*)GetProcAddress(h_dll, "hello_dll");if (hello_dll) {hello_dll();} else {error_code = GetLastError();printf("can't get valid function entry, error code: %d\n", error_code);}FreeLibrary(h_dll);} else {error_code = GetLastError();printf("load library fail, error code: %d\n", error_code);}printf("\n__end__\n");}</span>

修改为指定“dll”的路径,这样不用修改代码或重新编译,就能同时测试Debug & Release版本的dll。此外引用了“hello_dll.h”这样就不用再写引用函数的类型定义,更加容易理解了。

Windows + mingw dll的创建和使用实验

在移植到Linux平台下面之前,先用mingw的gcc实验看看。

为了方便gcc & msvc共Code编译,并有更简单的对比测试环境。在dll_note同一个目录下创建obj、exe两个目录。在msvc 中设置“dll_demo”Project输出“dll_demo.exe”到exe目录下:



这样就让msvc & gcc编译的exe都输出到exe目录,dll都输出到lib目录。

先尝试用gcc编译hello_dll.c文件:

<span style="font-family:Microsoft YaHei;font-size:18px;">\dll_note>gcc -c -D BUILD_DLL -I .\inc .\src\hello_dll.c -o .\obj\hello_dll.o.\src\hello_dll.c: In function '_declspec':.\src\hello_dll.c:15:1: error: expected '=', ',', ';', 'asm' or '__attribute__'before '{' token { ^In file included from .\src\hello_dll.c:12:0:.\inc/hello_dll.h:21:28: error: declaration for parameter 'hello_dll' but no such parameter  _declspec(dllexport) void hello_dll(void);                            ^.\src\hello_dll.c:17:1: error: expected '{' at end of input } ^</span>

gcc有编译出错,因为gcc与msvc不同,不需要_declspec(dllexport)修饰符来导出Symbol到dll,只需要加-shared选项就可。为了让msvc & gcc公用一份code,对“hello_dll.h”做了如下修改:

<span style="font-family:Microsoft YaHei;font-size:18px;">#ifndef __hello_h_#define __hello_h_#ifdef __cplusplusextern "C" {#endif#ifdef BUILD_DLL#  if defined (__GNUC__)#define DLL_EXPORT#  elif defined(_MSC_VER)#define DLL_EXPORT _declspec(dllexport)#  else#define DLL_EXPORT#  endif#endif#ifdef BUILD_DLLDLL_EXPORT void hello_dll(void);#elsevoid (*hello_dll)(void);#endif#ifdef __cplusplus}#endif#endif /* #ifndef __hello_h_ */</span>


增加了DLL_EXPORT宏的定义,以区分msvc & gcc对dll export 函数Symbol的修饰符。让msvc和gcc可以共用这份Code。这样修改后gcc就能让“hello_dll.c”正常编译通过了。

为了便于用gcc编译dll和exe,写了如下makefile

Makefile

<span style="font-family:Microsoft YaHei;font-size:18px;"># this make file for dll study used by Water (sszhouplus@qq.com)TGT_DLL = .\lib\gcc_hello_dll.dllTGT_EXE=.\exe\gcc_dll_demo.execc = gcc.PHONY:allall: .\obj\gcc_hello_dll.o .\obj\gcc_dll_demo.o$(cc) -shared -o $(TGT_DLL) .\obj\gcc_hello_dll.o$(cc) -o $(TGT_EXE) .\obj\gcc_dll_demo.o.\obj\gcc_dll_demo.o: .\src\dll_demo.c .\inc\hello_dll.h$(cc) -c -o $@ $< -I .\inc.\obj\gcc_hello_dll.o: .\src\hello_dll.c .\inc\hello_dll.h$(cc) -c -o $@ $< -I .\inc -D BUILD_DLL.PHONY:cleanclean:del /f /q .\obj\gcc_dll_demo.odel /f /q .\obj\gcc_hello_dll.odel /f /q $(TGT_DLL)del /f /q $(TGT_EXE)</span>

执行编译结果如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">.\note\dll_note>mingw32-makegcc -c -o .\obj\gcc_hello_dll.o .\src\hello_dll.c -I .\inc -D BUILD_DLLgcc -c -o .\obj\gcc_dll_demo.o .\src\dll_demo.c -I .\incgcc -shared -o .\lib\gcc_hello_dll.dll .\obj\gcc_hello_dll.ogcc -o .\exe\gcc_dll_demo.exe .\obj\gcc_dll_demo.o</span>

运行结果如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">.\note\dll_note>.\exe\gcc_dll_demo.exe .\lib\gcc_hello_dll.dllstart load libraryget function entry from dll by symbol namehello dll__end__</span>

可见exe和dll都符合预期了。

接下来再做一些交叉测试,分别用msvc的dll_demo.exe测试gcc生成的gcc_hello_dll.dll,再用gcc生成的gcc_dll_demo.exe 测试msvc生成的hello_dll.dll。按照预期的应该都能够正常调用。

<span style="font-family:Microsoft YaHei;font-size:18px;">.\note\dll_note>.\exe\gcc_dll_demo.exe .\lib\hello_dll.dllstart load libraryget function entry from dll by symbol namehello dll__end__.\note\dll_note>.\exe\dll_demo.exe .\lib\gcc_hello_dll.dllstart load libraryget function entry from dll by symbol namehello dll__end__</span>

从结果可以看出都能够正常执行,实验达到了预期的效果。

同一份Code分别用msvc & gcc可以通过编译,并且生成的exe和dll都能够互相调用,体现了dll的独立性与编译器无关。


在MinGW下用Linux API显示调用dll实验

上面例子的dll_demo.c里面使用的仍然是windows的API来Load/Get/Free dll。Mingw支持使用Linux的方式来操作dll。

下面创建dll_demo_linux.c来实验Linux dll/so的使用方法。

1. 增加include Linux 调用dll相关的函数头文件是 <dlfcn.h>

2. 用dlopen 代替LoadLibrary 加载dll

3. 用dlsym 代替 GetProcAddress 获得dll symbol对应的函数入口地址

4. 用dlclose 代替 FreeLibrary 用于释放dll

5. 用dlerror 代替 GetLastError 获得出错信息

dll_demo_linux.c源代码如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <stdio.h>#include <dlfcn.h>#include "hello_dll.h"void main(int argc, char **argv){void *h_dll;char *p_err_str;if (argc < 2) {printf("cmd fmt: <dll path>\n");return;}printf("start load library\n");h_dll = dlopen(argv[1], RTLD_LAZY);if (h_dll) {printf("get function entry from dll by symbol name\n");hello_dll = dlsym(h_dll, "hello_dll");if (hello_dll) {hello_dll();} else {p_err_str = dlerror();printf("can't get valid function entry, error code: %s\n", p_err_str);}dlclose(h_dll);} else {p_err_str = dlerror();printf("load library fail, error code: %s\n", p_err_str);}printf("\n__end__\n");}</span>

创建相应的Makefile_linux.mk如下:

<span style="font-family:Microsoft YaHei;font-size:18px;"># this make file for dll study used by Water (sszhouplus@qq.com)TGT_DLL = .\lib\gcc_hello_dll.dllTGT_EXE=.\exe\gcc_dll_demo_linux.execc = gcc.PHONY:allall: .\obj\gcc_hello_dll.o .\obj\gcc_dll_demo_linux.o$(cc) -shared -o $(TGT_DLL) .\obj\gcc_hello_dll.o$(cc) -o $(TGT_EXE) .\obj\gcc_dll_demo_linux.o.\obj\gcc_dll_demo_linux.o: .\src\dll_demo_linux.c .\inc\hello_dll.h$(cc) -c -o $@ $< -I .\inc.\obj\gcc_hello_dll.o: .\src\hello_dll.c .\inc\hello_dll.h$(cc) -c -o $@ $< -I .\inc -D BUILD_DLL.PHONY:cleanclean:del /f /q .\obj\gcc_dll_demo_linux.odel /f /q .\obj\gcc_hello_dll.odel /f /q $(TGT_DLL)del /f /q $(TGT_EXE)</span>

执行make结果如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">.\note\dll_note>mingw32-make -f Makefile_linux.mkgcc -c -o .\obj\gcc_hello_dll.o .\src\hello_dll.c -I .\inc -D BUILD_DLLgcc -c -o .\obj\gcc_dll_demo_linux.o .\src\dll_demo_linux.c -I .\incgcc -shared -o .\lib\gcc_hello_dll.dll .\obj\gcc_hello_dll.ogcc -o .\exe\gcc_dll_demo_linux.exe .\obj\gcc_dll_demo_linux.o</span>

执行dll_demo_linux.exe,实验结果也符合预期,都能正常执行。

<span style="font-family:Microsoft YaHei;font-size:18px;">.\dll_note>.\exe\gcc_dll_demo_linux.exe .\lib\hello_dll.dllstart load libraryget function entry from dll by symbol namehello dll__end__.\note\dll_note>.\exe\gcc_dll_demo_linux.exe .\lib\gcc_hello_dll.dllstart load libraryget function entry from dll by symbol namehello dll__end__</span>

这样看来使用Linux API调用dll在mingw下也实验完毕了,接下来到Linux下看看。


Linux so的创建和使用实验

将src、inc拷贝到Linux环境下,并在同一个目录下创建lib和exe目录。根据Linux的特性,创建相应的makefile:“make_linux.mk”如下:

<span style="font-family:Microsoft YaHei;font-size:18px;"># this make file for dll study used by Water (sszhouplus@qq.com)TGT_DLL = ./lib/gcc_hello_dll.soTGT_EXE=./exe/gcc_dll_demo_linux.outcc = gcc.PHONY:allall: ./obj/gcc_hello_dll.o ./obj/gcc_dll_demo_linux.o-mkdir exe-mkdir lib$(cc) -shared -o $(TGT_DLL) ./obj/gcc_hello_dll.o$(cc) -o $(TGT_EXE) ./obj/gcc_dll_demo_linux.o -ldl./obj/gcc_dll_demo_linux.o: ./src/dll_demo_linux.c ./inc/hello_dll.h-mkdir obj$(cc) -c -o $@ $< -I ./inc./obj/gcc_hello_dll.o: ./src/hello_dll.c ./inc/hello_dll.h-mkdir obj$(cc) -c -o $@ $< -I ./inc -D BUILD_DLL.PHONY:cleanclean:-rm -f ./obj/gcc_dll_demo_linux.o-rm -f ./obj/gcc_hello_dll.o-rm -f $(TGT_DLL)-rm -f $(TGT_EXE)</span>

针对Linux环境下的makefile主要做了如下几点的修改

1. 将路径里面的“\”修改为“/”

2. 将windows的del 改为linux的 rm命令

3. 在生成执行文件的命令里面增加 -ldl的编译选项,这样就能找到dlopen/dlsym/dlclose等函数

4. 增加了-mkdir obj/lib/exe 创建目录的命令 (mkdir前面的“-”目的是让命令执行失败也不影响makefile继续执行)。

 

执行make后结果如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">~/note$ make -f make_linux.mkmkdir objgcc -c -o obj/gcc_hello_dll.o src/hello_dll.c -I ./inc -D BUILD_DLLmkdir objmkdir: 无法创建目录"obj": 文件已存在make: [obj/gcc_dll_demo_linux.o] 错误 1 (忽略)gcc -c -o obj/gcc_dll_demo_linux.o src/dll_demo_linux.c -I ./incmkdir exemkdir libgcc -shared -o ./lib/gcc_hello_dll.so ./obj/gcc_hello_dll.ogcc -o ./exe/gcc_dll_demo_linux.out ./obj/gcc_dll_demo_linux.o -ldl~/note$ ls ./exe/gcc_dll_demo_linux.out</span>

运行程序,结果如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">~/note$ ./exe/gcc_dll_demo_linux.out ./lib/gcc_hello_dll.so start load libraryget function entry from dll by symbol namehello dll__end__</span>


在Linux环境下即使没有修改source code,程序也能正常编译通过并正确运行了。

至此,msvc、mingw、linux gcc的动态链接库实验基本已经完成了,但还有点小遗憾,windows的msvc & linux gcc调用动态库的方式是不同的,demo的code虽然差异不大,但是还是有所不同。

接下来尝试一下对dll的使用接口进行简单封装一下,以便统一window msvc & linux gcc的dll使用接口,让更多的code可以共用。

Win msvc & Linux gcc dll Simple Common API

定义的Simple Common DLL API 头文件“com_dll_api.h”如下:

com_dll_api.h

<span style="font-family:Microsoft YaHei;font-size:18px;">#ifndef __com_dll_api_h_#define __com_dll_api_h_#ifdef __cplusplusextern "C" {#endif/**  * Function: dll_open  * @brief:   open dll library, and return dll module handle  * @param:   dll_name : [in] the dll file name for open  * @return:  void* the dll module handle  *              0  : error occurs during the process of loading dll file   *                More detailed diagnostic information will be available   *                  through dl_get_error  *              !0 : open dll libary ok and return the dll module handle  */void *dll_open(const char *dll_name);/**  * Function: dll_close  * @brief:   close dll module  * @param:   dll_module : [in] the dll module handle (by dll_open)  * @return:  void*   *              0  : close dll module ok  *              !0 : close dll mdoule ng, and return input dll_module  *                More detailed diagnostic information will be available   *                  through dl_get_error  */void *dll_close(void *dll_module);/**  * Function: dll_get_symbol  * @brief:   get function entry from dll module by symbol name  * @param:   dll_module : [in] the dll module handle (by dll_open)  *           sym_name:    [in] the symbol name for this function  * @return:  void*   *             0  : get function entry fail from this dll by this symbol name  *                More detailed diagnostic information will be available   *                  through dl_get_error  *             !0 : get function entry ok and return function pointer addresss  */void *dll_get_symbol(void *dll_module, const char *sym_name);/**  * Function: dll_last_error  * @brief:   after dll_open/close/get_symbol function failed  *             could get the last detailed error information by this function.  *           if dll_open/close/get_symbol return ok, and call this function  *            the error information maybe incorrect.  * @param:   null  * @return:  char*   *              0  : no error information  *              !0 : the last error information  */char *dll_last_error(void);#ifdef __cplusplus}#endif#endif /* #ifndef __com_dll_api_h_ */</span>

com_dll_api.c

<span style="font-family:Microsoft YaHei;font-size:18px;">#include "com_dll_api.h"#if defined (_MSC_VER)# include "com_dll_api_msvc.c"#elif defined (__GNUC__)# include "com_dll_api_linux.c"#else# pragma "error: tbd compiler"#endif</span>

com_dll_api_msvc.c

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <stdio.h>#include <wtypes.h>#include <winbase.h>#include <winerror.h>#include "com_dll_api.h"static char dll_msvc_error[64];void *dll_open(const char *dll_name){return LoadLibrary(dll_name);}void *dll_close(void *dll_module){if (FreeLibrary(dll_module))return 0;return dll_module;}void *dll_get_symbol(void *dll_module, const char *sym_name){return (void*)GetProcAddress(dll_module, sym_name);}char *dll_last_error(void){sprintf(dll_msvc_error, "msvc dll last error code: [%d]", GetLastError());return dll_msvc_error;}</span>

com_dll_api_linux.c

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <dlfcn.h>#include "com_dll_api.h"void *dll_open(const char *dll_name){return dlopen(dll_name, RTLD_LAZY);}void *dll_close(void *dll_module){if (0 == dlclose(dll_module))return 0;return dll_module;}void *dll_get_symbol(void *dll_module, const char *sym_name){return dlsym(dll_module, sym_name);}char *dll_last_error(void){return dlerror();}</span>

使用Simple Common Dll API开发的demo “dll_demo_com_dll_api.c”

dll_demo_com_dll_api.c

<span style="font-family:Microsoft YaHei;font-size:18px;">#include <stdio.h>#include "hello_dll.h"#include "com_dll_api.h"void main(int argc, char **argv){void *dll_module;char *p_err_str;if (argc < 2) {printf("cmd fmt: <dll path>\n");return;}printf("start load library\n");dll_module = dll_open(argv[1]);if (dll_module) {printf("get function entry from dll by symbol name\n");hello_dll = dll_get_symbol(dll_module, "hello_dll");if (hello_dll) {hello_dll();} else {p_err_str = dll_last_error();printf("can't get valid function entry,""error code: %s\n", p_err_str);}dll_close(dll_module);} else {p_err_str = dll_last_error();printf("load library fail, error code: %s\n", p_err_str);}printf("\n__end__\n");}</span>

这样无论windows的的msvc还是linux的gcc都可以用这套com_dll_api.h来进行dll的调用了。可以实现一份Code用msvc & linux gcc都能够使用。

测试代码和工程的整理

前面测试的代码是一边学,一边实践,一边改进,又跨了多个编译器和平台,有点乱乱的。

在这里整理一下。

测试工程结构如下:

study_dll

├─build

│  ├─linux

│  ├─mingw

│  └─msvc

│      ├─com_dll_api

│      ├─hello_dll

│      └─test_dll

├─doc

├─lib

├─src

│  ├─com_dll_api

│  └─hello_dll

└─tests

 

最终整理后打包的工程和测试代码可以到Water的网盘下载: 

http://pan.baidu.com/s/1sjDLDVn

也可以用Git到Water在Oschina上AudioKits中的项目下载:

http://git.oschina.net/webwater/AudioKits/tree/master/study_space/study_dll

学习笔记的PDF档案也可到Water的网盘下载:

http://pan.baidu.com/s/1zxd9s


参考文献

1. “VC++动态链接库(DLL)编程深入浅出”

http://pan.baidu.com/s/1jG46yhg

 

2. “LINUX系统中动态链接库的创建与使用 ”

http://www.cnblogs.com/ardar/articles/357321.html


0 0
原创粉丝点击