起源
前段时间面试遇到这样一个问题:“封装dll时需注意哪些事项”,当时不知道题意,更理不清思路,当然,整个面试也挂掉了。
现在看来,这个题目有点太大了,刨去dll位数等不讲,我们针对dll中传递stl这种情况进行分析。
现象
在使用vs2010调用opencv2.4.10这个版本的findcontours函数时,传入了vector<vector<cv::point>> 这样的参数进去,后来运行时函数退出的时候一直崩溃,进去看是vector析构的时候出现的问题。该部分代码在vs2017+opencv3.4.0上运行是毫无问题的,网上别人的解决办法有:
1、提前开辟固定大小的空间
2、修改c++运行时
3、opencv版本配置问题等
上述方法尝试后仍无效果,迫于无奈,只好用c接口的函数来实现,并且再未出现崩溃的现象。
原因分析
其实该现象是一个典型的cross-dll problem,这在《effective c++》中编写一个清晰且不易出错的接口规则中有提到。就opencv的findcontours函数来说,我们在程序中创建了vector<vector<cv::point>> contours这样一个变量,在传入findcontours函数时,在opencv的dll中会增加和开辟内存,等到程序跳出当前函数的作用域,释放contours的内存时便会崩溃。此时项目配置为MTD,若将项目配置成MD的,程序便不会崩溃,即vs2017+opencv3.4.0不会崩溃的原因。其深层次的原因是在MT运行库下,windows会为dll和我们写的程序分别创建