1

我正在开发一个在 Xcode 中混合了 Objective C 和 C++ 的静态库A,我遇到了“弱链接”另一个静态库的需要,我们称之为BA调用B中定义的一些方法。这个想法是,如果B没有链接/提供,A将不会抛出任何未定义的符号错误。我知道在Objective C中你可以做到这一点,在代码中我可以依靠运行时方法,如NSClassFromString或[someObject Class]来检查某个函数是否存在/是否可从另一个静态库中获得,但我不知道是否我可以在我的一个 .cpp 源文件中实现这一点。请指教,谢谢!

为了说明目的,我创建了一个非常简单的示例项目:

图书馆A

Core_ObjC.h,这是要暴露的头文件

#import <Foundation/Foundation.h>

@interface Core_Objc : NSObject

-(int) calculate;

@end

Core_ObjC.mm

#import "Core_ObjC.h"
#include "Core_CPP.h"

@implementation Core_Objc

-(int) calculate{
    return calculate_Core();//Call into cpp here
}

@end

Core_CPP.cpp

#include "Core_CPP.h"
#include "NonCore_CPP.h"

int calculate_Core(){
    return calculate_NonCore();//Call into another cpp here but it's defined in Library B
}

图书馆B

NonCore_CPP.cpp

#include "NonCore_CPP.h"

int calculate_NonCore(){
    return 100;
}

如果我在示例应用程序中链接这两个库,则该应用程序将正常编译。但是,当我从示例应用程序中仅链接 A 时,我会遇到如下错误:

Undefined symbols for architecture arm64:
  "calculate_NonCore()", referenced from:
      calculate_Core() in CoreFramework(Core_CPP.o)

该错误对我来说确实有意义,因为B将缺少定义,但我只是在寻找一个解决方案,当只有A时编译不会抱怨。

4

1 回答 1

0

因此,弱链接也适用于 C 函数级别。有关详细信息,请参阅 Apple 的文档,但基本上,该符号需要使用 声明__attribute__((weak_import)),如下所示

extern int MyFunction() __attribute__((weak_import));
extern int MyVariable __attribute__((weak_import));

然后你可以检查它的地址是否为零以检查它是否在链接时间内找到,使用例如if (MyFunction != NULL)if (&MyVariable != NULL)

您的标题提到了静态库。请注意,静态库只是目标文件的集合,因此您要么链接库,要么不链接;静态库没有弱链接,因为根据定义,它存在于构建时。或不。如果您想要运行时行为,请使用动态库。(dylib)

上面实际上应该涵盖您给出的示例:您只需要在calculate_NonCore不可用时提供替代代码,因为您不能在不使程序崩溃的情况下调用它。(有道理,不见了)

您也提到了 C++,尽管您的代码没有明显使用它。C++ 使这变得有点复杂,因为它的名字很混乱。此外,类本身没有任何链接,因此您无法测试类的存在。编译器似乎允许将该weak_import属性应用于成员函数、静态成员变量等,但我不确定NULL检查的工作程度。自由函数当然不应该成为问题——像对待 C 函数一样对待它们——我猜静态成员可能是一个很好的候选者,因为你可以很容易地获取它们的地址。

我可能会尽量避免调用任何使用可能不存在的类的任何部分的代码,并进行设置,以便您可以简单地检查“金丝雀”静态成员变量或函数的存在,如果存在,您可以得出结论,整个班级都在场。

于 2020-07-24T15:14:09.870 回答