年前快速的学习了dll的生成及使用,颇为得意。年后修改了下源码,再生成dll并测试的时候出现了问题,对dll的工作原理大概理解,但生成dll之前运行正常,之后就出现问题,而且又不能追踪错误,最多给出提示dll有bug,偶也跳到free.c中的if (retval == 0)句。总之,很郁闷。尤其是试过所以版本的源码生成dll都不行,简直不敢相信我的眼睛。
期间,看过dll的一篇详解(c++DLL 学习之路),讲的不错,主要关注了dll输出函数的两种方法(def文件和函数前__declspec(dllexport)).
另外,根据提示有说因为跨模块释放内存的问题,以为我也跨模块释放内存了,遂跟人学也输出一个函数专门释放dll中申请的内存。仍不对,就算不释放内存也不对。后明白,我的dll都是内部申请内存,然后dll自己又释放的,不存在跨模块的问题。跨模块是dll中申请内存,然后调用dll的这一头去把内存delete掉。不能跨模块是因为不同模块的内存分配和管理不同。
怀疑最多的是vs2008的配置的问题,因为这个是我最头疼的,代码可以检查推敲,可配置实在复杂难懂。使用我的dll的同学也没有了我曾给他的生成dll的工程文件夹,重新开始的路都堵死了。
而后,因为报告的是dll的错,索性看看到底何处的错,将输出函数里面只留一条返回语句。结果,仍然报相同的错误。我看了一眼参数列表,里面有三个string类型,忽然感觉到问题所在了。删掉这三个参数之后果然,不报错了。百度之,发现csdn有贴子称,dll输出函数的参数适宜用内置类型,不适宜用第三方类库的类型,应该用char * 代替string。可转念一想,貌似年前就用string做参数了,可还是觉得我记错了应该。问使用dll的同学,得到的答复是年前的接口函数中就有string参数,见鬼啊。不过,幸运的是这次,同学终于找到了一个年前给他的生成dll的工程,我如获至宝。将其中的dll拿来之后,仍旧报错。想想现在极有可能是测试dll的main函数的问题,传给dll输出函数的参数是不同的。将“古董”dll中的main拿来替上,果真正确了。再一细看,两个main里唯一的区别就是传给dll输出函数的string参数不同,或者说string长度不同,答案终于揭晓,string太长所以报错,够不够奇葩。过程太像推理小说了。
dll的接口使用的是c的那一套,给她c++的东西,他不消化。错是我犯的,但这也反应了语言的缺陷。要么不能用string,使用后直接报错,要么就支持的完美点,支持成这样很让人蛋疼。