开发者

Mixed C++/CLI code with unmanaged SQLite

开发者 https://www.devze.com 2023-04-12 02:19 出处:网络
I tried to use Mixed Mode of C++/CLI to manipulate with SQLite. I wrote this code: int rc; char*sql, *Sig, *DocName, *OrgName,*From,*To,*Date;

I tried to use Mixed Mode of C++/CLI to manipulate with SQLite. I wrote this code:

    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);

This code tries to write to the file TTest into the table Norm1Tab which has six columns, however it fails to write any thing!! Any idea can help to fix the problem?

Edit:

I noticed something strange to me, actually I did compile the previous code on Windows XP SP3 machine and it showed the problem described. But when I compile it on Windows 7 machine it works fine without doing any modification! Also I tried to compile it on XP machine and then copy the binary file with 'sqlite3.dll' and the 'data file' to Win7 and it worked very well!

On Windows XP I had tried a lot of modifications without any benefit, but I am now with this gist:

My project has OpenFileDialog object which is called by a button Button1 that differs from the button Button2 that calles the code shown above. The strange thing is that when I click on Button1 then click on Button2 the code of SQLite do nothing, while if I click on Button2 before Button1 the code works fine! This is only on Windows XP which is the targeted system.

Here is the code of Button1 handler:

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开发者_StackOverflow中文版, 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);
         }

Any one here can see the problem!


Possible problems:

Did you check that the file was opened properly? Does your table have only six columns? Is the table created already? Are the types of the table, the correct ones (i.e TEXT if needed)?

At the end of the code of button1 you have the line

this->maskedTextBox7->Text=HexSig;

You use maskedTextBox7->Text for the sql query. Is this String compatible with the proper value in the table (the first column)?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号