Search code examples
c++cwindowssqlitebuilder

Using sqlite3_load_extension with a windows DLL


Can anyone tell me where I'm going wrong here? I'm using C++ bulder 10.2 (clang compiler). From IDE menu I've selected File|New|Dynamic Link Library and chosen compile as C with no dependencies. I've then added sqliteFcts.c and made the sqliteFcts.dll library. It all compiles fine.

Contents of sqliteFcts.c.

#include <sqlite3ext.h>

SQLITE_EXTENSION_INIT1

#ifdef _WIN32
__declspec(dllexport)
#endif

int sqlite3_sqliteFcts_init(
  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);

  return rc;
}

// My code is above. Code below was created by the IDE
#pragma argsused
int _libmain(unsigned long reason)
{
  return 1;
}

From my own app I try to use the dll with the following code

int rc;

sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1,&rc);

rc=sqlite3_load_extension(db,"C:/temp/sqliteFcts.dll",0,&buf);

I get the error message "The specified procedure could not be found". From what I've read windows expects _libmain to be the Entry Point but sqlite expects sqlite3_sqliteFcts_init to b e the Entry Point and I've no idea how to resolve that or if that is even the problem.


Solution

  • I finally got it working but with a loose end.

    Firstly in this line

    rc=sqlite3_load_extension(db,"C:/temp/sqliteFcts.dll",0,&buf);
    

    I supplied a null for the 3rd parameter (the entry point) thinking sqlite would resolve this however sqlite would've supplied sqlite3_sqlitefcts_init (note lower case f) as the entry point so, inevitably, the function wouldn't be found. The line should read

    rc=sqlite3_load_extension(db,"C:/temp/sqliteFcts.dll","sqlite3_sqliteFcts_init",&buf);
    

    That said, it still didn't work. After advice I received on the sqlite forum I downloaded Dependency Walker and found the function listed as _sqlite3_sqliteFcts_init (note opening underscore) although I've no idea why. Anyway, I changed the above line to

    rc=sqlite3_load_extension(db,"C:/temp/sqliteFcts.dll","_sqlite3_sqliteFcts_init",&buf);
    

    and it worked. That was for a 32 bit implementation. I later discovered that when it was compiled as a 64 bit app the opening underscore wasn't required. If anyone can throw any light on this quirk I'd be grateful.