如何使用objective-C加载dylib或.a(静态库)文件?

时间:2014-01-27 07:49:37

标签: objective-c macos .net-assembly

C#代码:( windows)

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

我希望在Mac中实现相同的功能,其中AssemblyPath是静态库(libTEST.a)或dylib文件的路径。在Objective-C(Mac)中可以吗? 我试过NSBundle。但我想要一些好的解决方案。

2 个答案:

答案 0 :(得分:12)

首先,这与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");

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

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

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

完成图书馆后,请将其丢弃:

dlclose(handle);

答案 1 :(得分:0)

我还要补充一下,您需要从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