從__acrt_first_block == header 談起,記錄dll鏈接不一致的問題


 

           最近寫了一個postgresql的數據庫連接池dll。寫的比較隨意,某個頭文件如下:

#pragma once

#include "common.h"
#include "PgConnParam.h"
#include <vector>

namespace pgPool
{
class PGCONNPOOL_API CPgConnStmt
{
public:
CPgConnStmt(ConnReqst* connRqst);
~CPgConnStmt();

public:

//by execute sql statement directly
bool ExeStatement(std::string sql);

//by by execute sql statement indirectly
bool Create(std::string SqlString);
bool BindParameter(CPgConnParam& param);
bool ExeStatement();

bool GetErrorMsg(std::string & msg);

bool GetNext();
bool GetFieldValue(const char* strFieldName, std::string &Val);
//bool GetBlobValue(const char* strFieldName, std::string &Val); //postgresql 結果集無法返回同時是二進制和文本的內容
bool GetFieldValue(const char* strFieldName, int &Val);
bool GetFieldValue(const char* strFieldName, double &Val);

long long GetAffectedRows();


private:
CPgConnStmt();
void Free();
private:
PGresult *m_pResultSet;
ConnReqst* m_connRqst;
int m_row;
int m_totalrow;
std::string m_sql;
std::vector<CPgConnParam> m_param;
};

}

然后編譯的話一堆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了。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM