Смешанный код C ++ / CLI с неуправляемым SQLite - PullRequest
1 голос
/ 08 октября 2011

Я пытался использовать Mixed Mode C ++ / CLI для манипуляции с SQLite. Я написал этот код:

    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, в которой есть шесть столбцов, однако он ничего не записывает !! Любая идея может помочь решить проблему?

Edit:

Я заметил кое-что странное для меня, на самом деле я скомпилировал предыдущий код на компьютере Windows XP SP3, и он показал описанную проблему. Но когда я компилирую его на Windows 7 машине, он работает без каких-либо изменений! Также я попытался скомпилировать его на компьютере с XP, а затем скопировать двоичный файл с «sqlite3.dll» и «файлом данных» в Win7, и это сработало очень хорошо!

В Windows XP я перепробовал множество модификаций без какой-либо выгоды, но теперь я с этой сущностью:

В моем проекте есть объект OpenFileDialog, который вызывается кнопкой Button1, отличной от кнопки Button2, вызывающей код, показанный выше. Странно то, что когда я нажимаю 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);
         }

Любой здесь может увидеть проблему!

1 Ответ

1 голос
/ 14 октября 2011

Возможные проблемы:

Вы проверили, что файл был открыт правильно? В вашей таблице только шесть столбцов? Таблица уже создана? Являются ли типы таблицы правильными (т. Е. ТЕКСТ при необходимости)?

В конце кода кнопки 1 у вас есть строка

this->maskedTextBox7->Text=HexSig;

Вы используете maskedTextBox7-> Text для запроса SQL. Совместима ли эта строка с правильным значением в таблице (первый столбец)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...