I use a statically linked library for Sqlite in an iPhone Xcode project. I am now trying to include a .C extension to Sqlite in this project. However, I am having trouble making the Sqlite in the build SEE the extension.
The statically linked Sqlite library works fine. Also the .C extension works on my desktop, and builds fine as a statically linked library in Xcode. However, the custom functions it defines are missing when called.
For example, I load the extension as so with no errors.
SELECT load_extension('extension_name.so');
But when I try to call a function defined in the extension, 开发者_开发技巧I get this message
DB Error: 1 "no such function: custom_function"
Does anyone know much about linking a Sqlite extension into an Xcode project?
As said by @jbworld you cannot load dynamic libraries on the iPhone, so this link should be made statically, at compilation time. While reading at the code of spatialite (that's an SQLite extension), I found that kind of invocation:
void spatialite_init (int verbose) {
/* used when SQLite initializes SpatiaLite via statically linked lib */
sqlite3_auto_extension ((void (*)(void)) init_static_spatialite);
}
And the init_static_spatialite
code:
static void init_static_spatialite (sqlite3 * db, char **pzErrMsg,
const sqlite3_api_routines * pApi)
{
SQLITE_EXTENSION_INIT2 (pApi);
/* setting the POSIX locale for numeric */
setlocale (LC_NUMERIC, "POSIX");
*pzErrMsg = NULL;
sqlite3_create_function (db, "spatialite_version", 0, SQLITE_ANY, 0,
fnct_spatialite_version, 0, 0);
sqlite3_create_function (db, "proj4_version", 0, SQLITE_ANY, 0,
fnct_proj4_version, 0, 0);
sqlite3_create_function (db, "geos_version", 0, SQLITE_ANY, 0,
fnct_geos_version, 0, 0);
sqlite3_create_function (db, "GeometryConstraints", 3, SQLITE_ANY, 0,
fnct_GeometryConstraints, 0, 0);
sqlite3_create_function (db, "CheckSpatialMetaData", 0, SQLITE_ANY, 0,
fnct_CheckSpatialMetaData, 0, 0);
...
So it looks like if the sqlite_auto_extension
enables you to statically link an extension. The documentation seems to confirm that:
“This API can be invoked at program startup in order to register one or more statically linked extensions that will be available to all new database connections.”
Then, at runtime, for spatialite, I just have to invoke the spatialite_init(0)
to get the extension up and running.
Invoke such method before loading any sqlite DB.
Hope this helps.
Would it be possible for you to build your custom functions directly into your main executable, and tell sqlite about them with sqlite3_create_function?
I don't know what details apply in this situation, but I do recall that the iPhone is funny about loading code at runtime.
The function load_extension loads a shared library (.so). This is not allowed on the iPhone. You will have to recompile your static library to include the extension you wish to use.
精彩评论