总结:编译dll时,如果未找到对应实现,编译是不会报错的。
报错问题:lnk2019 unresolved external symbol referenced in function
问题描述:
我在工程里面编写了一个dll的库A。然后想用另一个动态库B去调用动态库A。
调用时出现了上述问题。说有几个函数找不到。
问题查找:
1 我查看对应函数的声明和定义都是存在的。
2 然后我又去用了下vs中的dumpbin来看编译生成的.lib文件。发现里面确实没有对应的符号。
3 后来我发现这个lib里面有一部分函数的符号时存在的。我就把不行的那个几个函数移到了可以的的函数的那个文件中,发现居然可以了。
4 我发现可能是文件的问题。然后仔细看检查对应文件。后来发现是实现的cpp文件并没有引用对应的头文件。之前都是编译成静态库,用起来没有问题。改成动态库之后,就有了这个问题。
思考:
我理解的理解是对于静态库,cmake会把add_library中的文件都进行编译,然后放在lib里面。所以不引用也没有关系。
我还试了下改成静态库。然后添加include和不添加include这个文件其实对应的.lib对于这个函数符号出现的位置来讲没有变化。大概率可以理解为没有影响。然后静态库中如果没有对应的实现也不会报错。
但是动态库的话,会对每一个cpp中的函数进行编译。有__declspec(dllexport) 这个符号的,才会放到lib中,让别的库去调用。没有那个符号的,就会只会编译到dll中。然后如果有多余的.h文件,即使这个.h中有cpp重名的函数,且有导出符号。编译器都会无视。
我还试了一下在dll中找不到那种非导出函数的符号。估计是成为了二进制代码了。
解决办法:就是为对应的cpp加上h文件。