c++ - 将 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 是入口点,我不知道如何解决这个问题,或者这是否是问题所在。
解决方案
我终于让它工作了,但有一个松散的结局。
首先在这一行
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 位应用程序时,不需要开头的下划线。如果有人能对这个怪癖有所了解,我将不胜感激。
推荐阅读
- java - Back4App 上传一个小文件但抛出错误:无法对未保存的 ParseFile 进行编码
- angular - Ionic Firebase 应用程序中的 getAccountInfo Google 调用缓慢和负载阻塞
- java - 如何检查一个字符是否为空
- azure - 使用 MySQL-in-App 为应用服务创建数据库
- java - 线程和 ArrayIndexOutOfBoundsException
- reactjs - redux 操作成功后清除表单
- java - 在已有的 rest 服务中配置 Elastic Search
- android - 使用 google vr sdk 开发的用于与 android 统一的 VR 应用程序可以在带有 Daydream 的 Lenovo Mirage Solo 上使用吗?
- rest - 如何确保请求从固定页面命中 REST api?
- android - 使用 Okhttp 将字符串转换为 json