Skip to content

Run-Time Loadable Extensions

1. Overview

Extensions can also be statically linked with the application. The code template shown below will work just as well as a statically linked extension as it does as a run-time loadable extension except that you should give the entry point function ("sqlite3_extension_init") a different name to avoid name collisions if your application contains two or more extensions.

NOTE: 上面这段话是什么意思?结合下面的内容来进行理解: sqlite是允许load多个extension的,每个extension都需要有一个entry point function,如果都指定为sqlite3_extension_init的话,则就导致name collision了。为了解决这个问题,sqlite采用了一定的命名方案: sqlite3_X_init,参见原文的"2. Loading An Extension"章节。

NOTE: Extensions的两种使用方式:

1) statically linked

2) run-time load

2. Loading An Extension

NOTE: 本节介绍run-time load方法。下面是sqlite提供的方法:

1) C: sqlite3_load_extension()

2) SQL function: Load_extension(X,Y)

3) command-line shell, extensions can be loaded using the ".load" dot-command

无论哪种方式,非常重要的是对**entry point function**的指定。其实也可以不指定,sqlite的默认寻找规则能够自动找到**entry point function**。

For security reasons, extension loading is turned off by default. In order to use either the C-language or SQL extension loading functions, one must first enable extension loading using the sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1,NULL) C-language API in your application.

NOTE: 必须要首先开启才能够使用

3. Compiling A Loadable Extension

gcc -g -fPIC -shared YourCode.c -o YourCode.so

NOTE: 其实就是普通的编译so的方式

4. Programming Loadable Extensions

NOTE: 不同的类型的extension使用不同的实现

5. Persistent Loadable Extensions

The default behavior for a loadable extension is that it is unloaded from process memory when the database connection that originally invoked sqlite3_load_extension() closes.

However, if the initialization procedure returns SQLITE_OK_LOAD_PERMANENTLY instead of SQLITE_OK, then the extension will not be unloaded (xDlClose will not be invoked) and the extension will remain in process memory indefinitely. The SQLITE_OK_LOAD_PERMANENTLY return value is useful for extensions that want to register new VFSes.

To clarify: an extension for which the initialization function returns SQLITE_OK_LOAD_PERMANENTLY continues to exist in memory after the database connection closes. However, the extension is not automatically registered with subsequent database connections. This makes it possible to load extensions that implement new VFSes. To persistently load and register an extension that implements new SQL functions, collating sequences, and/or virtual tables, such that those added capabilities are available to all subsequent database connections, then the initialization routine should also invoke sqlite3_auto_extension() on a subfunction that will register those services.

NOTE:自动load、register特性非常重要。

对于**SQL functions**,貌似它们必须要persistently load and register

The vfsstat.c extension show an example of a loadable extension that persistently registers both a new VFS and a new virtual table. The sqlite3_vfsstat_init() initialization routine in that extension is called only once, when the extension is first loaded. It registers the new "vfslog" VFS just that one time, and it returns SQLITE_OK_LOAD_PERMANENTLY so that the code used to implement the "vfslog" VFS will remain in memory. The initialization routine also invokes sqlite3_auto_extension() on a pointer to the "vstatRegister()" function so that all subsequent database connections will invoke the "vstatRegister()" function as they start up, and hence register the "vfsstat" virtual table.

6. Statically Linking A Run-Time Loadable Extension

7. Implementation Details

SQLite implements run-time extension loading using the xDlOpen(), xDlError(), xDlSym(), and xDlClose() methods of the sqlite3_vfs object. These methods are implemented using the dlopen() library on unix (which explains why SQLite commonly need to be linked against the "-ldl" library on unix systems) and using LoadLibrary() API on Windows. In a custom VFS for unusual systems, these methods can all be omitted, in which case the run-time extension loading mechanism will not work (though you will still be able to statically link the extension code, assuming the entry pointers are uniquely named). SQLite can be compiled with SQLITE_OMIT_LOAD_EXTENSION to omit the extension loading code from the build.

NOTE: 关于dlopen,参见工程Linux-OS的Programming\Object-file\Shared-library