最近寫了一個postgresql的數據庫連接池dll。寫的比較隨意,某個頭文件如下:
#pragma once #include "common.h" namespace pgPool public: //by execute sql statement directly bool GetErrorMsg(std::string & msg); bool GetNext(); long long GetAffectedRows();
} |
然后編譯的話一堆warning
這個warning的原因我是知道的,就是std的東西都是模板實現的,包含頭文件的時候包含了模板類。對於不同的編譯環境,如vs2008與vs2015,std的實現方式可能不一致,就導致使用這個dll的模塊可能會有dll鏈接不一致的風險。
最好的規避方法是使用pImp模式,把std的細節包含在實現內,不要暴露給使用方。項目比較緊並且已經有人使用了,目前還沒改成正規的方式。
只要確保vs的編譯環境一致,目前還是可以用的。
然后就踩到了另外一個坑,編譯沒問題,調試的時候莫名其妙報了“__acrt_first_block == heade”的窗體。
出錯的地方在“bool Create(std::string SqlString)的函數結束處”
問題的原因是 模塊間一定要遵守“誰new誰delete的原則”,使用DLL的時候,問題可能在於不同的堆用於分配和釋放 引起的。
改為bool Create(std::string& SqlString) 后解決。
切記,編譯器的warning還是要重視的,以后寫dll,一定不要把std的東西暴露給用戶!
2017-9-5更新:
運行不久后還是報錯了,原因在於string傳入的時候如果長度不夠,會在dll模塊進行realloc,然后會造成不同模塊之間new與delete。
解決辦法,編譯成靜態庫或者不要使用dll了。。