【问题标题】:How to load dylib or .a (static library) file using objective-C?如何使用 Objective-C 加载 dylib 或 .a(静态库)文件?
【发布时间】:2014-01-27 07:49:36
【问题描述】:

C#代码:(windows)

Assembly assembly = Assembly.LoadFrom(AssemblyPath);
System.Type[] objTypes = assembly.GetTypes();
Type libType = null;

我想在 Mac 上实现同样的效果,其中 AssemblyPath 是静态库 (libTEST.a) 或 dylib 文件的路径。在Objective-C(Mac)中可能吗? 我尝试使用 NSBundle。但我想要一些好的解决方案。

【问题讨论】:

  • 你对 NSBundle 做了什么尝试,为什么它是一个“糟糕的解决方案”?那么 dlopen() 呢?在回答 stackoverflow.com/a/21338282/1187415 之前对您之前的类似问题提出了建议?
  • 顺便说一句,不要重复你的问题stackoverflow.com/questions/21325604/… 并忽略给定的答案,如果答案不能解决你的问题,你可以尝试改进问题或发表评论。
  • 嗨...我认为 .a(静态库)文件在 NSBundle 中不受支持。我用这个...类exampleClass; id 新实例; NSString *str = @"/Users/Desktop/libCDT.ChunkUtil.a"; NSBundle *bundleToLoad = [NSBundle bundleWithPath:str]; if (exampleClass == [bundleToLoad classNamed:@"IReaderClass"]) { newInstance = [[exampleClass alloc] init]; // [newInstance doSomething];但是 bundleToLoad 对象包含 Null 值...那该怎么办?

标签: objective-c macos .net-assembly


【解决方案1】:

首先,这与 Xcode 完全无关

现在,您不能动态加载静态库,因为静态库只是对象文件的集合,它们本身不是可执行的。

要加载动态库,请使用dlopen() API:

void *handle = dlopen("/path/to/library.dylib", RTLD_LAZY);

获取 C 函数指针:

int (*computeAnswer)(void) = dlsym(handle, "ComputeAnswer");
int answer = computeAnswer(); // 42

要获得没有extern "C" 链接的 C++ 函数指针(损坏的名称):

int (*mangledFunction)(void) = dlsym(handle, "i$mangledFunction_@v");

您甚至可以通过 linker 编译器的 Objective-C 命名约定来破解自己:

@class MyShinyClass;
Class cls = dlsym(handle, "OBJC_CLASS_$_MyShinyClass");

MyShinyClass *instance = [[cls alloc] init];

当你用完这个库后,把它扔掉:

dlclose(handle);

【讨论】:

  • @user3200854 不能。您不能动态加载静态库。
  • H2CO3 :感谢您的帮助。我创建了框架并使用 dlopen 函数加载。现在我有framework_handle。是否可以从 framework_handle 对象中获取类名?
  • 嗨...我已经通过使用 NSBundle 完成了这项工作。我正在动态加载框架。像这样... NSBundle *b = [NSBundle bundleWithPath:AssemblyPath]; if ( [b load] ){..} 现在我想要这个加载的框架中的所有类列表。我想检查它的基类型,即基类名称。如果基类名称与所需的类名称相同,那么我想创建该特定类的实例......这怎么可能?
  • @user3200854 您可以使用objc_getClassClist() 获取类列表,您可以通过查看其信息字典来获取与捆绑的主体类对应的字符串。有一个 NSPrincipalClass 键可以完全满足您的需求。
  • 嗨...但是我已经动态加载了我的框架..我只想要那个加载的框架中的所有类.. objc_getClassClist() 不返回类...我不想要那个.. .我只想要由框架动态加载的类。你能给我任何建议或反馈吗?请..
【解决方案2】:

我要补充一下前面所说的,您需要从 dlsym 中桥接类,它返回 C 类型 void*。

所以在这种情况下,这将意味着做一些事情:

@class MyShinyClass;
Class cls = (__bridge Class)dlsym(handle, "OBJC_CLASS_$_MyShinyClass");

MyShinyClass *instance = [[cls alloc] init];

请注意那里添加的(__bridge Class)

进一步参考: Pass an Objective-C object to a function as a void * pointer

【讨论】:

    猜你喜欢
    • 2014-08-09
    • 2012-09-29
    • 1970-01-01
    • 2012-01-29
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2013-08-19
    相关资源
    最近更新 更多