我已经将 sqlite3.c 构建到我的应用程序中,并将 extension-functions.c (hxxps://www.sqlite.org/contrib) 构建到一个共享库中并且它工作正常,但是对于我正在处理的项目我必须将 sqlite3 + 扩展函数静态链接到 C++ 应用程序中。 我已经阅读了很多关于这个主题的资料,但我无法让它发挥作用。
最小示例(test.cc):
#include "sqlite3.h"
#include<cstdlib>
void sqlite3_extension_functions_init(void);
// typedef struct sqlite3_api_routines sqlite3_api_routines;
// int sqlite3_extension_functions_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
int main(int argc,char *argv[]) {
// sqlite3_auto_extension( (void(*)(void))sqlite3_extension_functions_init );
sqlite3_auto_extension( sqlite3_extension_functions_init );
sqlite3 *database_;
sqlite3_open_v2("test.db", &database_, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
sqlite3_close_v2(database_);
return 0;
}
构建命令:
gcc -o test sqlite3.c extension_functions.c test.cc -lpthread -lm -ldl -DSQLITE_CORE
(-DSQLITE_CORE 没有影响?)
错误:
/tmp/ccPfaDLE.o: In function `main':
test.cc:(.text+0x10): undefined reference to `sqlite3_extension_functions_init()'
collect2: ld returned 1 exit status
改为使用注释行:
/tmp/ccrs9B0K.o: In function `main':
test.cc:(.text+0x10): undefined reference to `sqlite3_extension_functions_init(sqlite3*, char**, sqlite3_api_routines const*)'
collect2: ld returned 1 exit status
- 来自 SQLite 3.8.6 的 sqlite3.c、sqlite3.h、sqlite3ext.h
- extension_functions.c 来自 https://www.sqlite.org/contrib (重命名为 extension-functions.c)-> 根据 http://sqlite.1065341.n5.nabble.com/Example-Showing-ACTUAL-Use-of-sqlite3-auto-extension-td27657.html 修改静态链接并将
int sqlite3_extension_init()
重命名为int sqlite3_extension_functions_init()
我使用的其他来源:
- hxxp://books.google.de/books?vid=ISBN1449399649&q=209
- hxxps://www.sqlite.org/loadext.html
- hxxp://stackoverflow.com/a/1295765
可能是我瞎了,函数原型(prototype)在test.cc中给出,函数定义在extension_functions.c中。有人知道这个代码示例有什么问题吗?预先感谢您的帮助。(我很抱歉 hxxp://链接,但我不允许发布两个以上的链接)
最佳答案
混合使用 C 和 C++ 代码时,请确保在 C++ 端将 C 函数的声明标记为 C,如:
extern "C" {
int sqlite3_extension_functions_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi);
// more declarations
}
编译器为声明为 C 或 C++ 的外部变量生成不同的符号。错误消息反射(reflect):
test.cc:(.text+0x10): undefined reference to `sqlite3_extension_functions_init(sqlite3*, char**, sqlite3_api_routines const*)'
在这种情况下,编译器准备了一个符号名称,因为它认为它正在处理 C++ 函数,而实际上驻留在 extension_functions.c
中的函数将是一个 C 函数,链接器应该期望解析不同的符号名称。此错误消息指出链接器无法解析基于 C++ 命名法的符号名称。
顺便说一下背景。是C++支持函数重载,而C不支持。所以在 C++ 中你可以有两个不同的函数:
extern void foobar(int x, int y);
extern void foobar(char const *x);
为了区分,C++编译器为这些不同的函数分配了不同的符号,通常是将函数参数的原型(prototype)作为符号名的一部分。相比之下,像 int foobar()
这样带有任何函数参数的 C 函数只会生成符号 foobar
而符号名称中没有参数原型(prototype),因为简单的 C 不会有函数重载。
这就是为什么声明 C 函数但必须可用于 C 和 C++ 的头文件通常结构如下:
#ifdef __cplusplus
extern "C" {
#endif
/* Now follow declarations of C functions, such as extern int printf()
* or whatever
*/
#ifdef __cplusplus
}
#endif
关于c++ - 如何将 sqlite3 + 扩展函数静态链接到 C/C++ 应用程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28856061/