如何在Objective-c中找到sqlite3_load_extension [错误:找不到dlopen(...)图像]

时间:2010-02-21 03:11:48

标签: objective-c sqlite

我正在尝试加载sqlite3的扩展,以便在iPhone应用程序objective-c代码中使用。我成功地将新函数的c文件编译成名为libsqlitefunctions.dylib的dylib。这是我有点失落的地方。我按如下方式调用sqlite3_load_extension:

char * error = sqlite3_malloc(MAX_SQLITE_ERROR_MESSAGE_SIZE); const char * library = [@“libsqlitefunctions.dylib”UTF8String];

if(sqlite3_load_extension(database,library,0,& error)!= SQLITE_OK){   message = [NSString stringWithFormat:@“%s”,错误]; }

sqlite3_free(误差);

无论我做什么,我都会收到错误:dlopen(libsqlitefunctions.dylib,10):找不到图像

我试过了:

  1. 表示dylib的完全限定路径
  2. 表示相对路径
  3. 未指明路径(如上所示)
  4. 添加dylib作为框架
  5. 将.c文件添加到我的项目并将其编译为.o文件,然后尝试加载它
  6. 请注意,这不是入口点问题,因为我将arg作为0传递。这将通过调用dylib中定义的init函数来强制加载dylib。我甚至没有达到这一点。

    与其他人相比,我几乎是一个新手,并且觉得我可能对库的加载方式缺乏了解。

    我真的很感激任何想法,因为能够利用这个库中的功能对我的应用程序的功能很重要。提前谢谢大家。

5 个答案:

答案 0 :(得分:1)

好的,我接受了你的建议,只是将我的新功能添加到我项目中的sqlite3.c文件中。它静态编译和链接,工作正常。谢谢你的想法。我仍然想知道是什么阻止我加载扩展,但我很高兴在解决问题时学到了其他的东西 - 加上我遇到了我的截止日期。再次感谢你。

答案 1 :(得分:0)

我并非100%确定这是明确禁止的,但iPhone不支持其他类型的动态加载 - 框架。您可能需要静态编译和链接库,而不是动态编译。

答案 2 :(得分:0)

我知道话题很老。但谷歌搜索带我到这儿。并且对于有这个问题并且最终在这里的任何人: 你必须先打电话 sqlite3_enable_load_extension(db,1);

答案 3 :(得分:0)

我知道我回答的很晚,但我遇到了同样的问题,并找到了如何加载扩展程序。

获得源文件X.c后,使用

编译共享库(在Linux机器中)

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

其中X.c是使用中的扩展名

然后使用

启用C接口中的加载扩展到SQLite

sqlite3_enable_load_extension(db,1);

然后使用

加载扩展程序
sqlite3_load_extension(db,"/path/of/extension/X.so","sqlite3_X_init",0);

多数民众赞成,现在将加载扩展程序。

答案 4 :(得分:0)

经过几天的搜索,我终于找到了解决方案!

1)一旦你的sqlite_extension.h和sqlite_extension.c文件移入你的sqlite_extension文件夹

2)cd到sqlite_extension文件夹

3)使用以下代码编译代码:

gcc -g -fPIC -std=gnu99 -current_version 1.0 -compatibility_version 1.0 -dynamiclib -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk sqlite_extension.c -o sqlite_extension.dylib

您可能需要更改类似../iPhoneOSN.M.sdk的SDK路径,其中NM表示iOS的最新可用版本,请查看文件夹“/Applications/Xcode.app/Contents/Developer/平台/ iPhoneOS.platform / Developer / SDKs /“以查找现有路径

4)您可以使用以下方法检查生成的文件:

file /path/to/your/sqlite_extension.dylib

应该返回类似的内容:

/./././sqlite_extension.dylib (for architecture armv7): Mach-O dynamically linked shared library arm
/./././sqlite_extension.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library

或使用更详细的:

otool -l sqlite_extension.dylib

5)现在您的库需要使用与嵌入式应用程序相同的身份进行代码签名,您可以使用以下方法执行此操作:

codesign -fs "your_apple_identity" sqlite_extension.dylib

your_apple_identity的格式为“your_name:your_apple_login_email@address.xxx”

确保最好的方法是使用Xcode或计算机上的存档从您的设备上编译和运行的嵌入式应用程序可执行文件中复制一个:

codesign --display --verbose=4 ~/Library/Developer/Xcode/Archives/2016-09-25/YourApp\ 25-09-2016\ 12.00.xcarchive/Products/Applications/YourApp.app/YourApp

用于代替“your_apple_identity”的字符串是在第一次出现后发现的字符串=

6)您的图书馆代码签名后,您可以使用相同的命令检查您是否获得与您的应用程序类似的签名信息:

codesign --display --verbose=4 sqlite_extension.dylib

7)您的资源库现已准备好嵌入您的应用程序,您只需要确保Xcode刷新您的库文件,如果您尝试使用相同名称的先前文件。为此,您可以删除以前的文件,在您的设备上编译和运行,放回新文件,确保它位于“Copy Bundle ressources”中,而不是应用程序Build Phases选项卡的“Link Binary With Librairies”< / p>

当您的应用请求SQLite使用它时,您的扩展程序应该正确加载

iOS 9.3.5 Xcode 8.0 SQLite 3.9.2