我正在開發一個由主機應用程式加載的 SIMBL 插件macOS。它幾乎完全是用撰寫的,C 并且只有最少的 Objective-c 組件。(UI 主要由對主機應用程式的 API 呼叫提供。)其中一項要求是插件包可以從不同的子目錄多次加載。它是一個 Lua 解釋器,目標是為每個實體托管不同配置的 lua 腳本,這些腳本出現在主機應用程式的單獨選單中。第三方可以將此插件與其腳本的自定義配置捆綁在一起,它們將在應用程式的插件選單中顯示為單獨的專案。
我遇到的這個問題是:我需要找出我的插件在哪個目錄中執行。我可以創建一個名為MY_BUNDLE_ID_CLASS并使用的特殊類:
[NSBundle bundleForClass:[MY_BUNDLE_ID_CLASS class]];
一旦我有了正確的NSBundle,獲取檔案路徑就很簡單了。
問題是,如果我的包的多個實體被加載(從不同的檔案夾),Cocoa 抱怨這個類MY_BUNDLE_ID_CLASS是在多個位置定義的,并且不能保證我使用了哪個。對于其他類似的類,這對我的插件來說很好,因為我唯一的類名是等同于包含版本號的損壞名稱的宏,但在這種情況下它是不行的。它可能是同一版本的多個實體。有沒有其他方法可以找出我的插件代碼正在執行的檔案夾?這似乎是一個簡單的請求,但我卻空無一物。我歡迎建議。
uj5u.com熱心網友回復:
給定可執行檔案中的地址,該dladdr函式可用于向動態聯結器查詢包含該地址的動態鏈接影像;即,給定對插件中符號的參考,dladdr可以為您提供有關插件的動態鏈接資訊。
運行時查找可能如下所示:
// Sample: BundleClass.m, the principal class for the plugin
#import "BundleClass.h"
#import <dlfcn.h>
// We'll be using a reference to this variable compiled into the plugin,
// but we can just as easily use a function pointer or similar -- anything
// that will be statically compiled into the plugin.
int someVariable = 0;
@implementation BundleClass
(void)load {
Dl_info info;
if (dladdr(&someVariable, &info) != 0) {
NSLog(@"Plugin loaded from %s", info.dli_fname);
} else {
// Handle lookup failure.
}
}
@end
除了&someSymbol,您還可以使用對函式的參考(例如&someFunctionDefinedInThePlugin),但您應該注意不要傳入可以動態分配的指標 - 因為這可能會失敗,或者將您指向主機的記憶體空間程序。
在我的機器上,通過簡單的 macOS 主機應用程式設定,以下加載代碼:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:@"DynamicBundle" withExtension:@"bundle"];
if (!bundleURL) {
NSLog(@"Failed to find bundle!");
return;
}
NSLog(@"Bundle class before loading: %@", NSClassFromString(@"BundleClass"));
NSBundle *bundle = [NSBundle bundleWithURL:bundleURL];
NSError *error = nil;
if (![bundle loadAndReturnError:&error]) {
NSLog(@"Failed to load bundle: %@", error);
return;
}
NSLog(@"Bundle class after loading: %@", NSClassFromString(@"BundleClass"));
}
成功生產
Bundle class before loading: (null)
Loaded plugin from /Volumes/ExtSSD/Developer/Xcode/DerivedData/HostApp/Build/Products/Debug/HostApp.app/Contents/Resources/DynamicBundle.bundle/Contents/MacOS/DynamicBundle
Bundle class after loading: BundleClass
這確實是磁盤上插件的路徑。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/426051.html
標籤:目标-c 苹果系统 可可 nsbundle simbl
下一篇:在PHPhotoLibrarypresentLimitedLibraryPickerFromViewController崩潰,無法識別的選擇器發送到實體
