将 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 位应用程序时,不需要打开下划线。如果有人能对这个怪癖有所了解,我将不胜感激。
谁能告诉我哪里出错了? 我正在使用 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 位应用程序时,不需要打开下划线。如果有人能对这个怪癖有所了解,我将不胜感激。