??????? 由于項目的需要,需要用C++去連Oracle數據庫,Oracle版本為10g,在經過n次錯誤后終于成功連接。
?????? ?最開始用ADO連,裝上客戶端以后,在Oracle Net Manager中設置服務命名,測試連接成功,然后
設置ODBC數據源,測試也成功,ADO連接串寫上"DSN=xxx"就能連上了,但是在釋放連接時總是出錯,
經過多次嘗試后放棄,在網上看到Oracle專門為C++提供了連接的接口OCCI,于是嘗試采用這種方法。
??????? 一、安裝Oracle客戶端
??????????????? 安裝方式選擇為管理員。安裝完以后設置服務命名。在%ORACLIENTHOME%\NETWORK\ADMIN目錄下tnsnames.ora文件記錄了服務命名的設置。我的設置如下:
???????????????

ORCL_192.168.0.3?=
??(DESCRIPTION?=
????(ADDRESS_LIST?=
??????(ADDRESS?=?(PROTOCOL?=?TCP)(HOST?=?192.168.0.3)(PORT?=?1521))
????)
????(CONNECT_DATA?=
??????(SID?=?orcl)
??????(SERVER?=?DEDICATED)
????)
??)

ORCL?=
??(DESCRIPTION?=
????(ADDRESS_LIST?=
??????(ADDRESS?=?(PROTOCOL?=?TCP)(HOST?=?192.168.0.3)(PORT?=?1521))
????)
????(CONNECT_DATA?=
??????(SERVICE_NAME?=?ORCL_192.168.0.3)
????)
??)

其中192.168.0.3為遠程Oracle服務器IP地址
設置完以后在Net Manager中測試連接,成功就OK了。
????????二、設置VC++.net環境
??????? 我用的編譯器是VS2003,首先在工具---選項中Project添加包含文件%OracleClientHome%\Oci\include
添加庫文件%OracleClientHome%\Oci\lib\msvc\vc71和%OracleClientHome%\Oci\lib\msvc如果是VC6.0的話就
添加%OracleClientHome%\Oci\lib\msvc\vc6。
然后設置項目屬性,在編譯器---鏈接中添加lib文件,oraocci10d.lib,之后把oraocci10d.dll文件復制到system32目錄下,這個文件在VC71目錄下。
第三步在C++----代碼生成中設置運行時庫為多線程DLL或是多線程調試DLL,注意這一步設置很重要,
沒有設置的話會造成getString函數出錯。
??????? 三、代碼
???????

#include? " stdafx.h "
#include?
< occi.h >
using ? namespace ?std;
using ? namespace
?oracle::occi?;
int
?main()?
{
????Environment
* ?env = Environment::createEnvironment( " ZHS16GBK " ,? " UTF8 "
);
????
// Environment?*env=Environment::createEnvironment(Environment::DEFAULT);


????
string ?mc;
????
{
????????Connection?
* conn? = ?env -> createConnection( " system " ,? " system " ,? " orcl_192.168.0.3 "
);
????????
????????
try

????????
{
????????????Statement?
* stmt? = ?conn -> createStatement( " select?*?from?test1 "
);

????????????ResultSet?
* rs? = ?stmt ->
executeQuery();
????????????
while (rs -> next()? == ? true
)
????????????
{
????????????????mc
= rs -> getString( 1
);
????????????????cout?
<< ?mc? <<
?endl;
????????????}

????????????stmt
-> closeResultSet(rs);
????????????conn
->
terminateStatement(stmt);
????????}

????????
catch ?(SQLException?e)
????????
{
????????????cout
<<
e.what();
????????}

????????env
-> terminateConnection(conn);
????}

????Environment::terminateEnvironment(env);
????system(
" pause " );
????
return ? 0
;
}

orcl_192.168.0.3就是前面設置的連接串。
測試成功。以上就是所有的設置過程,唉,還是jdbc好連阿。。。

注意,項目屬性中運行時庫一定要設置為多線程DLL或是多線程調試DLL,否則getString函數就會出錯,我在這個問題上也卡了很長時間,單步調試發現是在string對象析購時出錯,在網上看到一篇文章得到答案。
??????? 原因是由于程序中使用的內存管理多來源于crt提供的例程,而非直接使用操作系統的接口,這些例程都需要維護一些module全局數據(例如維護池、維護空閑塊、或者標記已申請的塊等等,不同的實現中有不同的作用),當他們被靜態連編時,實際上這些“全局數據”就不“全局”了,不同的module各自為政,每份module都有自己的“全局數據”,自身的內存信息不為他人所知,module A的合法內存快自然不可能通得過module B的合法性驗證

解決問題的方法有:
1、不要跨module傳遞c++對象,或者避免釋放跨module申請的內存

2、將參與合作的module統統以multithreaded dll方式鏈入crt庫,讓他們的“全局”數據真正全局,注意,所有有交互的module都需要動態鏈入crt。