Search code examples
c++sqlitedll32-bitdev-c++

Is there a way to create a c++ 32-bit DLL that access SQLite database?


We are trying to build a c++ 32-bit DLL that access SQLite database.

Background: We have a lot of legacy 32-bit apps. Our long-term goal is to convert them to 64-bit using mostly c++ and wxWidgets. However, we cannot do this all at once because of the enourmous number of programming involved. So we decided to do this by installment.

What we have already done: Using C++ 32-Bit DLL, we have converted almost all global procedures and functions not involving access to database. We used Dev-C++ IDE, MinGW-w64 TDM-GCC 32-bit Release. We we able to compile the DLLs and the 32-bit apps were able to call them without problem.

Also, we were able to use SQLite with our apps using SQLite ODBC driver. However, we do not want to implement this with our clients because it involves installing the driver. Our apps are strictly confined is a single folder and we do not alter anything outside of this folder. Deployment is as simple as copying this folder in the client's drive.

Our problem: When we tried using SQLite in a DLL, it will compile only with a 64-bit compiler but the DLL will not load with 32-bit apps. The 32-bit compiler on the other hand, is not able to reference the methods of the SQLite interface (ex. undefined reference to 'sqlite3_open').

We suspect it has something to do with the link to libsqlit3.a which may be 64-bit. We tried compiling sqlite3.c with the 32-bit option:

gcc -m32 sqlite3.c -o sqlite3

but it generated a lot of errors.

Below is a sample of a DLL project in c++:

testsql.cpp

#include <iostream>
#include <string>
#include "testsql.h"
#include <c:\mingw32\opt\include\sqlite3.h> 

using namespace std;

char* sql_char(char* a)
{
    string s = "Hello ";
    string c = a;
    s = s + c;
    char *r = &s[0];
    return r;
}

/*
**Note: Without the following codes below, the project will compile to 32-bit DLL and will load in 32-bit apps**
*/

int sql_connect(string s)
{   
    sqlite3* DB;    
    int exit = 0; 
    exit = sqlite3_open("c:\\d\\SQLiteDB\\chinook.db", &DB); 
  
    if (exit) { 
        std::cerr << "Error open DB " << sqlite3_errmsg(DB) << std::endl; 
        return (-1); 
    } 
    else
        std::cout << "Opened Database Successfully!" << std::endl; 
        sqlite3_close(DB); 
        return (0); 
}

testsql.h

#pragma once 

#ifndef TESTSQL_EXPORTS
#define TESTSQL_API __declspec(dllexport)
#else
#define TESTSQL_API __declspec(dllimport)
#endif
using namespace std;

extern "C" TESTSQL_API char* sql_char(char* a);

extern "C" TESTSQL_API int sql_connect(char* s);
    

Any help will be appreciated.


Solution

  • Finally, after several days of trial and error, I was able to solve our problem. Here's how to create a c++ 32-bit DLL with access to SQLite database using DevCpp,:

    Download sqlite-amalgamation-3440000. It contains 4 files - sqlite3.c, shell.c, sqlite3.h and sqlite3ext.h.

    In the folder where you placed these file, create sqlite.o with these command (assuming you have gcc intalled and the folder containing it is included in your system paths)

    gcc -m32 sqlite3.c -c
    

    Note the -m32 is the for the 32-bit option.

    Going back to the DevCpp DLL project, I just added a link to the sqlite3.o file:

     Project>>Project Options>>Parameters>>Linker
    

    Then rebuild the project and compile with TDM-GCC 4.9.2 32-bit Release.

    I tried using the DLL in a VFP:

    DECLARE INTEGER sql_connect IN c:\d\clics3\SQLite\testsql\test2.dll STRING a
    ?sql_connect("test")
    

    Result: '0" The program executed without any error!