本文主要是介绍[NOTE] WindowsLinux动态链接库学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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 __cplusplus
extern "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 library
load 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 __cplusplus
extern "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 __cplusplus
extern "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>
为了便于用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.dll
TGT_EXE=.\exe\gcc_dll_demo.execc = gcc.PHONY:all
all: .\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:clean
clean: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-make
gcc -c -o .\obj\gcc_hello_dll.o .\src\hello_dll.c -I .\inc -D BUILD_DLL
gcc -c -o .\obj\gcc_dll_demo.o .\src\dll_demo.c -I .\inc
gcc -shared -o .\lib\gcc_hello_dll.dll .\obj\gcc_hello_dll.o
gcc -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.dll
start load library
get function entry from dll by symbol name
hello 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.
dll
start load library
get function entry from dll by symbol name
hello dll__end__.\note\dll_note>.\exe\dll_demo.exe .\lib\gcc_hello_dll.
dll
start load library
get function entry from dll by symbol name
hello 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.dll
TGT_EXE=.\exe\gcc_dll_demo_linux.exe
cc = gcc.PHONY:all
all: .\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:clean
clean: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.mk
gcc -c -o .\obj\gcc_hello_dll.o .\src\hello_dll.c -I .\inc -D BUILD_DLL
gcc -c -o .\obj\gcc_dll_demo_linux.o .\src\dll_demo_linux.c -I .\inc
gcc -shared -o .\lib\gcc_hello_dll.dll .\obj\gcc_hello_dll.o
gcc -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.dll
start load library
get function entry from dll by symbol name
hello dll
__end__.\note\dll_note>.\exe\gcc_dll_demo_linux.exe .\lib\gcc_hello_dll.dll
start load library
get function entry from dll by symbol name
hello 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.so
TGT_EXE=./exe/gcc_dll_demo_linux.out
cc = gcc.PHONY:all
all: ./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:clean
clean:-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.mk
mkdir obj
gcc -c -o obj/gcc_hello_dll.o src/hello_dll.c -I ./inc -D BUILD_DLL
mkdir obj
mkdir: 无法创建目录"obj": 文件已存在
make: [obj/gcc_dll_demo_linux.o] 错误 1 (忽略)
gcc -c -o obj/gcc_dll_demo_linux.o src/dll_demo_linux.c -I ./inc
mkdir exe
mkdir lib
gcc -shared -o ./lib/gcc_hello_dll.so ./obj/gcc_hello_dll.o
gcc -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 library
get function entry from dll by symbol name
hello 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 __cplusplus
extern "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
这篇关于[NOTE] WindowsLinux动态链接库学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!