2011-10-07 25 views
1

我試圖使用C++/CLI的Mixed Mode來使用SQLite進行操作。我寫了這個代碼:具有非託管SQLite的混合C++/CLI代碼

int rc; 
    char *sql, *Sig, *DocName, *OrgName,*From,*To,*Date; 
    sqlite3 *db; //Database handle 
    sqlite3_stmt *stmt; //used to handle stmt for step(), its is name prepared stmt 
    sql = "insert into Norm1Tab values (?,?,?,?,?,?);"; 
    sqlite3_open("TTest", &db); 

    Sig  =(char *)Marshal::StringToHGlobalAnsi(this->maskedTextBox7->Text).ToPointer(); 
    DocName =(char *)Marshal::StringToHGlobalAnsi(this->maskedTextBox2->Text).ToPointer(); 
    OrgName =(char *)Marshal::StringToHGlobalAnsi(this->maskedTextBox3->Text).ToPointer(); 
    From =(char *)Marshal::StringToHGlobalAnsi(this->maskedTextBox4->Text).ToPointer(); 
    To  =(char *)Marshal::StringToHGlobalAnsi(this->maskedTextBox5->Text).ToPointer(); 
    Date =(char *)Marshal::StringToHGlobalAnsi(this->maskedTextBox6->Text).ToPointer(); 

    rc= sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL);//compile sql to byte code 

    sqlite3_bind_text(stmt, 1, Sig, strlen(Sig),SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 2, DocName, strlen(DocName),SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 3, OrgName, strlen(OrgName),SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 4, From, strlen(From),SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 5, To, strlen(To),SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 6, Date, strlen(Date),SQLITE_TRANSIENT); 
    rc = sqlite3_step(stmt);//talk directly with VDBE and execute the bytecode 


    //free all handles and objects 
    Marshal::FreeHGlobal((IntPtr)Sig); 
    Marshal::FreeHGlobal((IntPtr)DocName); 
    Marshal::FreeHGlobal((IntPtr)OrgName); 
    Marshal::FreeHGlobal((IntPtr)From); 
    Marshal::FreeHGlobal((IntPtr)To); 
    Marshal::FreeHGlobal((IntPtr)Date); 
    sqlite3_finalize(stmt); 
    sqlite3_close(db); 

此代碼試圖寫入文件TTest到表Norm1Tab其中有六列,但是它不能寫任何東西!任何想法都可以幫助解決這個問題?

編輯:

我注意到一些奇怪的事情對我來說,我其實編譯Windows XP SP3機器前面的代碼,它顯示的問題描述。但是當我在Windows 7機器上編譯它時,它可以正常工作,不需要做任何修改!此外,我試圖在XP機器上編譯它,然後將'sqlite3.dll'和'數據文件'的二進制文件複製到Win7,它工作得很好!

在Windows XP中我嘗試了很多的修改沒有任何好處,但我現在有了這個要點是:

我的項目具有通過一個按鈕Button1從按鈕Button2是卡列斯的不同之稱爲OpenFileDialog對象上面顯示的代碼。奇怪的是,當我點擊Button1然後點擊Button2 SQLite的代碼什麼也不做,而如果我點擊Button2之前Button1代碼工作正常!這只是在目標系統的Windows XP上。

這是Button1處理程序的代碼:

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { 
if(openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK) 
     { 

     this->maskedTextBox1->Text=openFileDialog1->FileName->ToString(); 

     } 

HANDLE hFile; 
HANDLE hMap; 
//open the file// 
hFile = ::CreateFile((LPCWSTR)Marshal::StringToHGlobalUni(this->maskedTextBox1->Text).ToPointer(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 
           0,OPEN_EXISTING , FILE_FLAG_SEQUENTIAL_SCAN, 0); 

//get the size for creating the signature and mapping it to Virtual mem// 
unsigned long sifi=0; 
if(hFile !=INVALID_HANDLE_VALUE){ 
hMap= ::CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0);//create Mem mapping for the file in virtual memory 
sifi= ::GetFileSize(hFile,NULL); 
} 

//load the binary form of the file to memory// 
LPVOID base; 
BYTE b1,b2,b3,b4,b5,b6,b7,b8,b9,b10; 
int inc=2; 
if(hMap!=NULL){ 
base = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);//load the mapped file into the RAM 
b1= *((BYTE *)base + sifi/inc++); 
b2= *((BYTE *)base + sifi/inc++); 
b3= *((BYTE *)base + sifi/inc++); 
b4= *((BYTE *)base + sifi/inc++); 
b5= *((BYTE *)base + sifi/inc++); 
b6= *((BYTE *)base + sifi/inc++); 
b7= *((BYTE *)base + sifi/inc++); 
b8= *((BYTE *)base + sifi/inc++); 
b9= *((BYTE *)base + sifi/inc++); 
b10= *((BYTE *)base + sifi/inc++); 
} 
inc=2; 





//show the sig 
String^ HexSig; 
HexSig = String::Format("{0:X2}", b1)+String::Format("{0:X2}", b2)+String::Format("{0:X2}", b3)+String::Format("{0:X2}", b4)+String::Format("{0:X2}", b5)+String::Format("{0:X2}", b6)+String::Format("{0:X2}", b7)+String::Format("{0:X2}", b8)+String::Format("{0:X2}", b9)+String::Format("{0:X2}", b10); 
this->maskedTextBox7->Text=HexSig; 



//free handles 
    ::CloseHandle(hFile); 
    ::CloseHandle(hMap); 
    ::UnmapViewOfFile(base); 
     } 

這裏任何一個可以看到的問題!

+0

爲什麼在C++/CLI中使用'Marshal :: FreeHGlobal'時,你可以直接調用'GlobalFree'? –

+0

@Ben:'Marshal :: FreeHGlobal'暴露了'LocalFree'函數,而不是'GlobalFree',但是你的觀點依然存在。 – ildjarn

+0

@BenVoigt:因爲我使用了'元帥:: StringToHGlobalAnsi'!我不確定我是否理解你! – Aan

回答

1

可能存在的問題:

您是否檢查文件是否已正確打開?你的桌子只有六列嗎?表格已經創建好了嗎?表格的類型是否正確(例如,如果需要,請輸入TEXT)?

在Button1的代碼,你到底有沒有對SQL查詢行

this->maskedTextBox7->Text=HexSig; 

您使用maskedTextBox7->文本。 此字符串是否與表格中的正確值(第一列)兼容?