简体   繁体   English

你能像 Objc 一样弱链接(可选链接)C++ 中的 static 库吗?

[英]Can you weak link(optional link) a static library in C++ like Objc could?

I am developing a static library A with a mix of Objective C and C++ in Xcode, I run into the need to "weak link" another static library and Let's call it B . I am developing a static library A with a mix of Objective C and C++ in Xcode, I run into the need to "weak link" another static library and Let's call it B . A calls some methods defined in B . A调用B中定义的一些方法。 The idea is that if B is not linked/provided, A will not throw any undefined symbols error.这个想法是,如果B没有链接/提供, A将不会抛出任何未定义的符号错误。 I know that in Objective C you can do that and in code I can rely on run time methods such as NSClassFromString or [someObject Class] to check if a certain function is present/available from another static library, but I don't know if I can achieve that in one of my.cpp source file. I know that in Objective C you can do that and in code I can rely on run time methods such as NSClassFromString or [someObject Class] to check if a certain function is present/available from another static library, but I don't know if我可以在 my.cpp 源文件之一中实现这一点。 Please advise and thank you!请指教,谢谢!

I created a very simple sample project for illustration purpose:为了说明目的,我创建了一个非常简单的示例项目:

Library A :图书馆A

Core_ObjC.h, this is the header that will be exposed Core_ObjC.h,这是即将暴露的header

#import <Foundation/Foundation.h>

@interface Core_Objc : NSObject

-(int) calculate;

@end

Core_ObjC.mm 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 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
}

Library B :图书馆B

NonCore_CPP.cpp NonCore_CPP.cpp

#include "NonCore_CPP.h"

int calculate_NonCore(){
    return 100;
}

If I link both libraries in a sample app, the app will compile fine.如果我在示例应用程序中链接这两个库,则该应用程序将正常编译。 However, when I link only A from the sample app, I will encounter error like:但是,当我从示例应用程序中仅链接 A 时,我会遇到如下错误:

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

The error does make sense to me because B will have the missing definition, but I am just looking for a solution that the compilation won't complain when there is only A .该错误对我来说确实有意义,因为B将缺少定义,但我只是在寻找一个解决方案,当只有A时编译不会抱怨。

So, weak linking works at the C function level as well.因此,弱链接也适用于 C function 级别。 For details, see Apple's documentation but basically, the symbol needs to be declared using __attribute__((weak_import)) , as follows有关详细信息,请参阅 Apple 的文档,但基本上,该符号需要使用__attribute__((weak_import))声明,如下所示

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

and then you can check if its address is zero to check if it was found during link time, using eg if (MyFunction != NULL) or if (&MyVariable != NULL) .然后您可以使用例如if (MyFunction != NULL)if (&MyVariable != NULL)检查其地址是否为零以检查是否在链接期间找到它。

Your title mentions static libraries.您的标题提到了 static 库。 Note that static libraries are just collections of object files, so you either link the library or you don't;请注意,static 库只是 object 文件的 collections 文件,因此您要么链接库,要么不链接; there's no weak linking a static library, because by definition, it's present at build time.没有弱链接 static 库,因为根据定义,它存在于构建时。 Or not.或不。 If you want runtime behaviour, use a dynamic library.如果您想要运行时行为,请使用动态库。 (dylib) (dylib)

The above should actually cover the example you have given: you'll just need to provide alternative code for when calculate_NonCore is unavailable, as you can't call it without crashing the program.上面实际上应该涵盖您给出的示例:您只需要在calculate_NonCore不可用时提供替代代码,因为您无法在不使程序崩溃的情况下调用它。 (Makes sense, it's missing) (有道理,不见了)

You mention C++ too, although your code doesn't make any obvious use of it.您也提到了 C++,尽管您的代码没有明显使用它。 C++ makes this a little more complicated because of its mangled names; C++ 使这变得更复杂一些,因为它的名字错了; additionally, classes themselves don't have any linkage, so you can't test for presence of a class.此外,类本身没有任何链接,因此您无法测试是否存在 class。 The compiler seems to allow applying the weak_import attribute to member functions, static member variables, etc. but I'm not sure to what extent the NULL checks will work.编译器似乎允许将weak_import属性应用于成员函数、static 成员变量等,但我不确定NULL检查能在多大程度上起作用。 Free functions should certainly not be an issue - treat them like C functions - and I'd guess that static members are probably a good candidate because you can easily take their address.免费函数当然不应该成为问题 - 像 C 函数一样对待它们 - 我猜 static 成员可能是一个很好的候选人,因为您可以轻松获取他们的地址。

I'd probably try to avoid calling into any code that makes use of any part of a class that might not be there, and set things up such that you can simply check for the presence of a "canary" static member variable or function, which, if present, you can conclude that the whole class is present.我可能会尽量避免调用任何使用可能不存在的 class 的任何部分的代码,并进行设置以便您可以简单地检查是否存在“金丝雀” static 成员变量或 ZC1C425268E68394FCAB14如果存在,您可以得出结论,整个 class 都存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM