gpt4 book ai didi

c - 如何在 SQLite 中编译用户定义的函数

转载 作者:太空宇宙 更新时间:2023-11-04 07:40:53 25 4
gpt4 key购买 nike

我有一个示例 C 函数,我想将其附加到数据库 temp.sqlite(它来自 O'Reilly 的一本书,所以我知道它可以工作)。我阅读了本书和 sqlite.org 中的部分,但他们假设我知道如何以及在何处使用适当的设置编译这个东西。我在 Mac(使用 XCode)或 Ubuntu 上。

我对 C 语言的了解足以改变代码来执行我想要的操作,但我不知道如何从我的数据库 temp.sqlite 中调用它。

感谢您的帮助!我一直在琢磨这个!

更新:几个小时后,我从废弃的网页中收集了足够多的东西来创建编译命令并生成错误:

richard$ gcc -o wtavg wtavg.c -Wall -W -O2 -L/usr/local/lib -lsqlite3
wtavg.c: In function ‘wtavg_init’:
wtavg.c:63: warning: unused parameter ‘error’
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

FWIW,这里是 wtavg.c,它直接来 self 书中提供的 O'Reilly 网站:

/* wtavg.c */

#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1;

#include <stdlib.h>




typedef struct wt_avg_state_s {
double total_data; /* sum of (data * weight) values */
double total_wt; /* sum of weight values */
} wt_avg_state;


static void wt_avg_step( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
double row_wt = 1.0;
int type;
wt_avg_state *st = (wt_avg_state*)sqlite3_aggregate_context( ctx,
sizeof( wt_avg_state ) );
if ( st == NULL ) {
sqlite3_result_error_nomem( ctx );
return;
}

/* Extract weight, if we have a weight and it looks like a number */
if ( num_values == 2 ) {
type = sqlite3_value_numeric_type( values[1] );
if ( ( type == SQLITE_FLOAT )||( type == SQLITE_INTEGER ) ) {
row_wt = sqlite3_value_double( values[1] );
}
}

/* Extract data, if we were given something that looks like a number. */
type = sqlite3_value_numeric_type( values[0] );
if ( ( type == SQLITE_FLOAT )||( type == SQLITE_INTEGER ) ) {
st->total_data += row_wt * sqlite3_value_double( values[0] );
st->total_wt += row_wt;
}
}


static void wt_avg_final( sqlite3_context *ctx )
{
double result = 0.0;
wt_avg_state *st = (wt_avg_state*)sqlite3_aggregate_context( ctx,
sizeof( wt_avg_state ) );
if ( st == NULL ) {
sqlite3_result_error_nomem( ctx );
return;
}

if ( st->total_wt != 0.0 ) {
result = st->total_data / st->total_wt;
}
sqlite3_result_double( ctx, result );
}


int wtavg_init( sqlite3 *db, char **error, const sqlite3_api_routines *api )
{
SQLITE_EXTENSION_INIT2(api);

sqlite3_create_function( db, "wtavg", 1, SQLITE_UTF8,
NULL, NULL, wt_avg_step, wt_avg_final );
sqlite3_create_function( db, "wtavg", 2, SQLITE_UTF8,
NULL, NULL, wt_avg_step, wt_avg_final );

return SQLITE_OK;
}

最佳答案

用户定义的函数应该被编译为共享库文件:

gcc -shared -fPIC -o wtavg.so wtavg.c -lsqlite3

然后可以使用 SQLite 语句加载该共享库:

SELECT load_extension('/path/to/wt_avg.so', 'wtavg_init');

很遗憾Apple提供的sqlite3版本不支持加载共享库。您可以改用 MacPorts 中的 sqlite。链接到 sqlite 的 MacPorts 程序也应该能够以这种方式加载用户定义的函数。

当在另一个程序中使用 SQLite 时,出于安全原因,扩展加载机制可能会被禁用。例如,在 Python 中,您必须调用 con.enable_load_extension(True) 才能启用它。

关于c - 如何在 SQLite 中编译用户定义的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4161654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com