使用未解析的标识符 'PKCS7_type_is_signed'

Use of unresolved identifier 'PKCS7_type_is_signed'

我正在 swift 中编写收据验证代码,但 PKCS7_type_is_signed 宏有问题: 使用未解析的标识符 'PKCS7_type_is_signed'

除了为这个宏创建 Objective-C 包装器之外,还有什么方法可以在 Swift 中使用它吗?

包装器看起来像这样:

#import "OpenSSLWrapper.h"

#import "openssl/pkcs7.h"
#import "openssl/objects.h"

@implementation OpenSSLWrapper

+ (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio{
    return PKCS7_type_is_signed(bio);
}

@end

宏在 Swift 中不起作用。你必须写一个包装器。

Swift 无法从宏中识别类型信息。 Swift 编译器应该允许将哪种参数传递给该宏?因为无法识别,所以不会编译。

可能还值得一提的是,在 C/Objective-C 中,这些宏是简单的查找和替换。宏在编译前展开。如果这个宏确实展开了,它几乎肯定会展开成无法在 .swift 文件中编译的代码。

来自苹果 将 Swift 与 Cocoa 和 Objective-C

结合使用

Complex macros are used in C and Objective-C but have no counterpart in Swift. Complex macros are macros that do not define constants, including parenthesized, function-like macros. You use complex macros in C and Objective-C to avoid type-checking constraints or to avoid retyping large amounts of boilerplate code. However, macros can make debugging and refactoring difficult. In Swift, you can use functions and generics to achieve the same results without any compromises. Therefore, the complex macros that are in C and Objective-C source files are not made available to your Swift code.

正如 nhgrif 所指出的(谢谢 :-)),这里的 2 个选项使用包装器或仅扩展宏。

扩展宏:

# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)

func PKCS7_type_is_signed(pkcs:UnsafeMutablePointer<PKCS7>)->Bool{
    return OBJ_obj2nid(pkcs.memory.type) == NID_pkcs7_signed
}

func PKCS7_type_is_data(pkcs:UnsafeMutablePointer<PKCS7>)->Bool{
    return (OBJ_obj2nid(pkcs.memory.type) == NID_pkcs7_data)
}

包装器:

.h 文件:

#import <Foundation/Foundation.h>
#import "openssl/pkcs7.h"
#import "openssl/objects.h"

    @interface OpenSSLWrapper:NSObject
    + (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio;
    + (BOOL)PKCS7TypeIsData:(PKCS7*)contents;
    @end

.m 文件:

#import "OpenSSLWrapper.h"

@implementation OpenSSLWrapper

+ (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio{
    return PKCS7_type_is_signed(bio);
}

+ (BOOL)PKCS7TypeIsData:(PKCS7*)contents{
    return PKCS7_type_is_data(contents);
}


@end