首页 > 解决方案 > 将 sqlite3_load_extension 与 Windows DLL 一起使用

问题描述

谁能告诉我这里哪里出错了?我正在使用 C++ bulder 10.2(clang 编译器)。从 IDE 菜单中,我选择了 File|New|Dynamic Link Library 并选择了 compile as C with no dependencies。然后我添加了 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);

我收到错误消息“找不到指定的过程”。从我读过的内容来看,windows 期望 _libmain 是入口点,但 sqlite 期望 sqlite3_sqliteFcts_init 是入口点,我不知道如何解决这个问题,或者这是否是问题所在。

标签: c++cwindowssqlitebuilder

解决方案


我终于让它工作了,但有一个松散的结局。

首先在这一行

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

我为第三个参数(入口点)提供了一个空值,认为 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 位应用程序时,不需要开头的下划线。如果有人能对这个怪癖有所了解,我将不胜感激。


推荐阅读