2010-02-21 80 views
0

我想加載到iPhone應用程序目標代碼中使用sqlite3的擴展。我成功地將新函數的c文件編譯到名爲libsqlitefunctions.dylib的dylib中。這是我有點失落的地方。我調用sqlite3_load_extension,如下所示:如何從Objective-c [錯誤:dlopen(...)圖像未找到] sqlite3_load_extension

char * error = sqlite3_malloc(MAX_SQLITE_ERROR_MESSAGE_SIZE); const char * library = [@「libsqlitefunctions.dylib」UTF8String]; (sqlite3_load_extension(database,library,0,& error)!= SQLITE_OK){0} {0} {0} {0}消息= [NSString stringWithFormat:@「%s」,error]; }

sqlite3_free(error);

不管我做什麼,我得到的錯誤:dlopen的(libsqlitefunctions.dylib,10):未找到

我試着像:

  1. 指示對dylib完全合格的路徑
  2. 指示相對路徑
  3. 不是指示路徑(如上所示)
  4. 添加dylib作爲框架
  5. 將.c文件添加到我的項目中,並將其編譯爲.o文件,然後嘗試加載它

請注意,這不是入口點問題,因爲我將0傳遞爲arg。這將通過調用dylib中定義的init函數來強制dylib加載。我甚至沒有明白這一點。

與其他人相比,我幾乎是一個新手,並且覺得我可能對圖書館的加載方式缺乏瞭解。

我真的很感激任何想法,因爲使用這個庫中的函數的能力對我的應用程序的功能很重要。謝謝大家。

回答

0

我不是100%確定這是明確不允許的,但另一種類型的動態加載 - 框架 - 在iPhone上不受支持。您可能需要靜態編譯和鏈接庫,而不是動態編譯。

+0

感謝您的回覆。我實際上試圖最初靜態鏈接。但是,我無法在.o文件上調用sqlite3_load_extension函數。我現在試圖重新設計.c代碼,以便擴展庫中的函數是同一個sqlite3.c代碼的一部分。 是否有其他人在iPhone上的objective-c中調用了sqlite3_load_extension? – user273565 2010-02-21 14:54:49

+0

我敢肯定,這是*不允許在iPhone上,因爲動態加載代碼要求該文件既可讀又可執行,並且您不允許在iPhone上執行權限。這與' - [NSBundle load]'不起作用的原因相同。 – 2010-02-21 17:07:27

1

好的,我接受了您的建議,並簡單地將我的新功能添加到我在項目中使用的sqlite3.c文件中。它編譯和鏈接靜態並正常工作。謝謝你的想法。我仍然想知道是什麼阻止了我加載擴展程序,但對於在解決問題時學到了其他東西感到高興 - PLUS我滿足了我的最後期限。再次感謝你。

0

我知道話題老了。但是使用谷歌搜索將我帶到這裏。對於任何有這個問題並最終在這裏的人: 您必須先調用 sqlite3_enable_load_extension(db,1);

0

我知道我回答遲了,但我面臨同樣的問題,並且發現如何加載擴展。

一旦你有源文件X.C,編譯使用

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

其中Xc是使用在使用

然後使裝載擴展在C接口的SQLite擴展名的共享庫(在Linux機器)

sqlite3_enable_load_extension(db,1);

然後使用加載擴展名

sqlite3_load_extension(db,"/path/of/extension/X.so","sqlite3_X_init",0); 

這就是它,擴展名將被加載。

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 

您可能需要更改SDK路徑,例如../iPhoneOSN.M.sdk,其中NM指示iOS的最後可用版本,查看文件夾「/Applications/Xcode.app/Contents/Developer/Platforms/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:[email protected]

,以確保最好的辦法是在一個從你的嵌入式應用程序可執行文件編譯和您的設備和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刷新你的庫文件,如果你已經嘗試使用相同名稱的以前的文件。爲此,您可以刪除以前的文件,在您的設備上進行編譯並運行,將新文件放回到您的應用程序的「構建階段」選項卡的「複製包資源」中,而不是「文件夾鏈接二進制文件」

然後

你的擴展名應該沒有錯誤加載當你的應用程序請求的SQLite使用它


的iOS 9.3.5 的Xcode 8.0 SQLite的3.9.2