【问题标题】:Declare a variable or function in one library and define it in another在一个库中声明一个变量或函数并在另一个库中定义它
【发布时间】:2013-01-28 20:27:43
【问题描述】:

我在所有应用程序中都使用了一个库,其中包含通用代码。我将它编译为 Mac 的“框架”和 iOS 的“静态库”。

我希望库能够引用由最终包含项目定义的变量。

例如库有一个函数:

void printAppID(void);

void printAppID(void) {
    NSLog(@"App ID is: %@", kAppID);
}

如果没有声明这个变量,库自然会抛出警告,所以我将它声明为:

NSString *kAppID;

由于库事先不知道kAppID(每个项目都不同),最终项目会执行以下操作:

NSString *kAppID = @"ABCD1234"

这会引发编译器错误:

未定义的建筑符号

我尝试过使用extern,或将其设为函数,或#define,但无法破解。

在库中声明变量并在其他地方定义变量的规范方式是什么?我认为这在 C 中和在 Obj-C 中是一样的。

编辑:更普遍的情况

我怎样才能拥有一个包含在应用程序项目中的已编译静态库以及一个 Constants.h 头文件,其值可以在该项目中编辑并由库使用?

【问题讨论】:

    标签: objective-c c frameworks forward-declaration


    【解决方案1】:

    规范的方法可能是在库中的某处有一个setAppID 方法,应用程序必须调用该方法来设置 ID。

    也就是说,kAppID 是库的一部分:

    static NSString* kAppID = nil;
    
    void setAppID (NSString* appID) {
        kAppID = appID;
    }
    
    // ...library can use kAppID as necessary...
    

    【讨论】:

    • 这是我现在正在使用的,它可以工作。不幸的是,它仍然需要库的使用者进行一些“编程”,而不仅仅是更改文本值,所以我不确定我是否真的应该将其标记为正确答案。除非我想要做的只是无法完成。
    • 我很高兴它有效!虽然我不确定如果图书馆的用户必须进行一些编程,为什么这是一个问题 - 他们肯定必须这样做才能实际使用您的图书馆?这种方式只需要一个额外的函数调用,并且不会比添加一个额外的变量更多的工作。此外,它增加了封装——这通常被认为是一件好事。
    【解决方案2】:

    extern 是正确的方法。

    在你的库中:

    extern NSString* const kAppID;
    

    在您的项目中的某个地方:

    NSString* const kAppID = @"ABCD1234";
    

    在您的库中使用可以从您的项目中配置的单例对象可能是一种更好的方法。但是,如果您希望链接器在未设置某些内容时崩溃,那么使用 extern 是正确的方法。

    【讨论】:

    • 对不起,这不能编译。同样的错误。我喜欢您的其他建议,但这需要子类化或具有某种其他类型的代码内例程,这对于共享库(甚至与我自己)来说很尴尬。
    • @SG1 如果你得到一个未定义的符号,那么你在链接库时做错了。 extern 肯定会工作。您必须在项目中定义符号。
    • Jonathan,您必须定义符号可能是对的 - 这似乎是问题所在。但是,如果您再次查看该问题,您会发现问题的本质是在库项目中声明了符号,但直到使用库的编译版本的应用程序项目才定义它 - 如果我能得到它编译,即。
    • @JonathanCichon 我给了你+1,因为我就是这样做的,但我已经多次被不同的开发人员告知这很糟糕,包括这里的开发人员,你能解释一下为什么会这样吗?如果你知道不好?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2012-07-31
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多