与宏的extern功能

Eug*_*Lim 3 macros objective-c extern

当我尝试使用extern函数进行marco时,我在Objective C中遇到了链接器问题.知道为什么吗?

头文件
帮助与设备版本进行比较

extern NSString* getOperatingSystemVerisonCode();

#if TARGET_OS_IPHONE // iOS
#define DEVICE_SYSTEM_VERSION                       [[UIDevice currentDevice]      systemVersion]
#else // Mac
#define DEVICE_SYSTEM_VERSION                       getOperatingSystemVerisonCode()
#endif

#define COMPARE_DEVICE_SYSTEM_VERSION(v)            [DEVICE_SYSTEM_VERSION compare:v options:NSNumericSearch]
#define SYSTEM_VERSION_EQUAL_TO(v)                  (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  (COMPARE_DEVICE_SYSTEM_VERSION(v) != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     (COMPARE_DEVICE_SYSTEM_VERSION(v) != NSOrderedDescending)
Run Code Online (Sandbox Code Playgroud)

.mm文件

NSString* getOperatingSystemVerisonCode()
{
    /*
     [[NSProcessInfo processInfo] operatingSystemVersionString]
     */
    NSDictionary *systemVersionDictionary =
    [NSDictionary dictionaryWithContentsOfFile:
     @"/System/Library/CoreServices/SystemVersion.plist"];

    NSString *systemVersion =
    [systemVersionDictionary objectForKey:@"ProductVersion"];
    return systemVersion;
}
Run Code Online (Sandbox Code Playgroud)

链接器错误:

Undefined symbols for architecture x86_64:
  "_getOperatingSystemVerisonCode", referenced from:
      -[Manager isFeatureAvailable] in Manager.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 6

问题不是由宏定义引起的.

getOperatingSystemVerisonCode()函数在".mm"文件中定义,因此编译为Objective- C++.特别是,函数名称被破坏为C++函数.但是当从(Objective-)C源引用时,预期会出现未编码的名称.

您有两种方法可以解决问题:

  • 将".mm"文件重命名为".m",以便将其编译为Objective-C文件.

  • 在声明函数的头文件中,extern "C"即使在(Objective-)C++文件中,也要添加声明以强制执行C链接:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    NSString* getOperatingSystemVerisonCode();
    
    #ifdef __cplusplus
    }
    #endif
    
    Run Code Online (Sandbox Code Playgroud)

有关混合C和C++的更多信息,请参阅示例