打包dll
如果要打包的函数分布在不同的文件中,在相应的每个头文件和源文件都做如下修改即可。
头文件
1 | #ifdef PREG_API |
源文件
1 | PREG_API_EXPORT result *my_detect(char *datacfg, char *cfg, network *net, char *filename, float thresh, float hier_thresh, int *objects_num) |
配置
exe —> dll
在预编译选项中加入PREG_API
编译程序即可得到 .dll 和 .lib
调用dll
头文件
在CPP文件中调用dll
1 | // 使用了extern "C" _declspec(dllimport),main文件必须为cpp文件,否则会出现error C2059: syntax error : 'string' |
若想在CPP或者C文件中同时可以使用,下面的extern "C"
表示在cpp中使用c语言的规则调用c文件产生的库。
1 | // 这种调用方式可以被main.c与main.cpp使用 |
源文件
直接使用即可
dll中结构体
无法使用,直接在调用dll的头文件中声明相同的结构体即可
dll的调试
将最新的dll和lib放在调用工程代码相同目录,直接debug,打断点,单步调试,VS会自动查找源文件所在的目录并打开。
注意事项
- 打包dll的环境(如x64,release)要与调用dll的代码环境设置一致,否则会报错
- windows下不能将结构体或者结构体指针返回,除非调用子函数的代码中包含子函数的头文件。
- 若VS调试的时候,出现了跳转不正常,断点的位置不正常,中断所停位置与实际不符等情况,删除中文注释。
当程序涉及到读取文件的时候,注意路径问题。第一种方法是使用绝对路径,第二种方法是使用下面代码打印当前工作目录,对相对路径进行修改。
1
2
3
4
5
6
7
8// Linux
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
// windows
char buf[80];
_getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);在windows下含有
static inline
的头文件在debug
模式下编译报错,在头文件添加下面语句1
2
3#if defined(WIN32) && !defined(__cplusplus)
#define inline __inline
#endif当打包dll的环境在
x64,debug
下时,调用dll的程序代码目录下要放入打包程序所调用的第三方dll文件,否则提示找不到该dll。但是x64,release
下就没有这个问题。- 若程序会读取配置文件等信息,又报错了,首先怀疑是路径问题。
- 调用32位debug版本的时候,注意把库依赖的第三方库也改为32位的。
- 若没有生成lib,但是有dll,重新生成工程即可。
- 64位程序训练出的参数文件、配置文件等在32位程序还可以运行,并且32位程序读取文件时仍然按64位文件读。要注意的是,分配给32位程序的内存比64位小,因此可能需要启用大地址。
- 在Qt下调用dll,若出现传参到dll中的函数后,路径(文件名等)为乱码,可能是参数错位或者参数个数不对。