将 sqlite3_load_extension 与 windows DLL 一起使用

Using sqlite3_load_extension with a windows DLL

谁能告诉我哪里出错了? 我正在使用 C++ bulder 10.2(clang 编译器)。从 IDE 菜单中,我选择了文件|新建|动态 Link 库并选择编译为 C,没有依赖项。然后我添加了 sqliteFcts.c 并创建了 sqliteFcts.dll 库。一切都编译得很好。

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

在我自己的应用程序中,我尝试使用具有以下代码的 dll

int rc;

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

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

我收到错误消息 "The specified procedure could not be found"。根据我的阅读,windows 期望 _libmain 成为入口点,但 sqlite 期望 sqlite3_sqliteFcts_init 成为入口点,我不知道如何解决这个问题,或者这是否是问题所在。

我终于让它工作了,但没有结局。

这一行排在第一位

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

我为第三个参数(入口点)提供了一个 null,我认为 sqlite 会解决这个问题,但是 sqlite 会提供 sqlite3_sqlitefcts_init(注意小写 f)作为入口点,因此,不可避免地,函数不会被发现。该行应显示为

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

也就是说,还是不行。在 sqlite 论坛上收到建议后,我下载了 Dependency Walker 并发现该函数列为 _sqlite3_sqliteFcts_init(注意开头的下划线),但我不知道为什么。无论如何,我将上面的行更改为

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

它奏效了。那是针对 32 位实现的。后来我发现,当它被编译为 64 位应用程序时,不需要打开下划线。如果有人能对这个怪癖有所了解,我将不胜感激。