sqlite 3.7.17 を Windows 95対応にしてみた

SQLITE 3.7.17 のWindows 向けライブラリをコンパイルしてみたよ
SQLITE 3.7.14.1 をビルドしてみた

前回作った sqlite3.dll 当然 Visual Studio 2005で作られてるので、Windows 95では非対応エクスポート関数が含まれてるのだけど、これを解決してもデータベースが読めない

トレースしてみたところ、 FileのOpenでこけてる。
よく見たら Windows 9x 非対応の OVERLAPPED を使用してた。

#if SQLITE_OS_WINCE
  if( seekWinFile(pFile, offset) ){
    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
    return SQLITE_FULL;
  }
  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
#else
  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(offset & 0xffffffff);
  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
         osGetLastError()!=ERROR_HANDLE_EOF ){
}

変更前

if( !isNT() ){
  if( seekWinFile(pFile, offset) ){
    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
    return SQLITE_FULL;
  }
}
else{
  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(offset & 0xffffffff);
  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
}

while( !osReadFile(pFile->h, pBuf, amt, &nRead, isNT()?(&overlapped):0) && ( !isNT() || osGetLastError()!=ERROR_HANDLE_EOF) ){

変更後

#if SQLITE_OS_WINCE
  rc = seekWinFile(pFile, offset);
  if( rc==0 ){
#else
  {
#endif

#if SQLITE_OS_WINCE
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
#else
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif

変更前

  if(isNT() || (seekWinFile(pFile, offset)==0)){

#if !SQLITE_OS_WINCE
    OVERLAPPED overlapped;        /* The offset for WriteFile. */
#endif
    u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
    int nRem = amt;               /* Number of bytes yet to be written */
    DWORD nWrite;                 /* Bytes written by each WriteFile() call */
    DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */

#if !SQLITE_OS_WINCE
  if(isNT()){
    memset(&overlapped, 0, sizeof(OVERLAPPED));
    overlapped.Offset = (LONG)(offset & 0xffffffff);
    overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
  }
#endif

変更後

コンパイル済みバイナリ。

その3 サンプルコードを動かしてみよう
ここのサンプルをちょっといじってみた

#include "stdafx.h"
#include <windows.h>
//#include <tchar.h>
#include "sqlite3.h"
#include <stdio.h>

typedef int (__cdecl * pOpen)(wchar_t *, sqlite3 **);
typedef int (__cdecl * pExec)(sqlite3 *, const char *, sqlite3_callback, void *, char **);
typedef int (__cdecl * pClose)(sqlite3 *);

pOpen sqlite3_open2;
pExec sqlite3_exec2;
pClose sqlite3_close2;

// 抽出結果が返るコールバック関数
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   for(i=0; i<argc; i++)
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   return SQLITE_OK;
}
HINSTANCE hSQDll;
 main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
//   printf("SQLite 1\n");
   hSQDll = LoadLibrary("sqlite3.dll");
   if(hSQDll==NULL){
     printf("SQLiteのライブラリがありません。\nsqlite3.dllがあることを確認して下さい。\n");
     return;
// sqlite3関数のアドレスを取得
  }
   else{
    sqlite3_open2 = (pOpen)GetProcAddress(hSQDll, "sqlite3_open16");
    sqlite3_exec2 = (pExec)GetProcAddress(hSQDll, "sqlite3_exec");
    sqlite3_close2 = (pClose)GetProcAddress(hSQDll, "sqlite3_close");
  }
 //  printf("SQLite exec\n");
   // データベースファイルを新規生成
   int rc = sqlite3_open2(L"SAMPLE.DB", &db);
   // テーブル生成SQL文
   char create_sql[] = "CREATE TABLE sample ( "
                       "               id     INTEGER PRIMARY KEY, "
                       "               worker TEXT    NOT NULL,    "
                       "               place  TEXT    NOT NULL     "
                       "             )                             ";
   // テーブルを生成
   rc = sqlite3_exec2(db, create_sql, 0, 0, &zErrMsg);

   if(zErrMsg){
       printf("%s\n",(char*)zErrMsg);
   }
   // データ追加SQL文
   char insert_sql[] = "INSERT INTO sample ( id, worker, place )"
                       "            values (%d, '%s', '%s')     ";
   // 追加SQL文を生成
   char insert_record[3][256];
   sprintf( insert_record[0], insert_sql, 0, "IKD"  , "Tokyo" );
   sprintf( insert_record[1], insert_sq
l, 1, "Maru" , "Kanagawa" );
   sprintf( insert_record[2], insert_sql, 2, "Nacky", "Hukuoka" );
   // データ追加
   int i;
   for( i = 0; i < 3; i++ ){
      rc = sqlite3_exec2(db, insert_record[i], 0, 0, &zErrMsg);
       if(zErrMsg){
           printf("%s\n",(char*)zErrMsg);
       }
   }
   // "sample"テーブルから"worker"を抽出して列挙
   rc = sqlite3_exec2(db, "SELECT worker FROM sample", callback, 0, &zErrMsg);
   if(zErrMsg){
       printf("%s\n",(char*)zErrMsg);
   }
  // データベースを閉じる
   sqlite3_close2(db);
}

Win95上でのテスト

C:\sqlitest>sqlitest
worker = IKD
worker = Maru
worker = Nacky

C:\sqlitest>sqlitest
table sample already exists
PRIMARY KEY must be unique
PRIMARY KEY must be unique
PRIMARY KEY must be unique
worker = IKD
worker = Maru
worker = Nacky

ダウンロード
sqlite3.7.17.2.cab

c++ - SQLite can't open database in Win98 - Stack Overflow
調べてみたら、困ってる人がいた

SQLite - Running on windows 98

何でこんなことやったかというと、もふったーのログ管理を sqlite にしたら もっとコンパクトになるんじゃないかって考えたからなんだな・ω・

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です