【问题标题】:How to efficiently wrap a C-library into Swift class如何有效地将 C 库包装到 Swift 类中
【发布时间】:2014-09-12 20:32:41
【问题描述】:

我想将一个 C 库(处理一些与 NumberTheory 相关的项目,我在大约 20 年前用 C 语言编写)包装到 Swift 中。我开始为这个 C 库编写一个 Objective-C 包装器,然后从 Objective-C 包装器编写一个 Swift 派生类。
由于 Objective-C 不允许我编写重载的方法/操作符,我想在 Swift 中完成。有问题的 C 库具有以“numthe”开头的 API 调用以及一个 libnumthe.a 和一个“numthe.h”包含文件。 Objective-C 包装器/类称为 NumTheObjC 和 Swift 类 NumThe

目前我有以下代码用于 NumTheObjC.h 文件:

#import <Foundation/Foundation.h>
#import <stdio.h>
#import "numthe.h"
@interface NumTheObjC : NSObject
{
    numthe_prime nPrime;     // Holds a numthe_prime number type instance.
    numthe_perfect nPerfect; // Holds a numthe_perfect number type instance.
    //... more numthe types/structure instances here.
}
-(id)init;                  // Default initializer
-(id)init:(NSString *)str;  // Initialize from string-value.
-(void)add:(NumTheObjC *)op;                                     // a += b
+(NumTheObjC *)add:(NumTheObjC *)left right:(NumTheObjC *)right; // x = a + b
-(void)setFromInt:(signed int)nrInt;        // Initialize/set from int.
-(void)setFromLong:(signed long)nrLong;     // Initialize/set from long.
-(void)setFromUInt:(unsigned int)nrUInt;    // Initialize/set from uint.
-(void)setFromULong:(unsigned long)nrULong; // Initialize/set from ulong.
@end

对于 Swift 包装器,我提出了 NumThe.swift 文件:

class NumThe : NumTheObjC {
    init(nr: Int) {
        super.init()
        setFromInt(nr)
    }
    init(nr: UInt) {
        super.init()
        setFromUInt(nr)
    }
    init(strNr: String) {
        super.init(strNr)
    }
    //... more overloaded 'constructors/initializers here ...
}
//-- Overloaded operator a + b
func + (inout left: NumThe, right: NumThe) -> NumTheObjC {
    return NumTheObjC.add(left, right: right)
}
//-- Overloaded operator +=
func += (inout left: NumTheObjC, right: NumThe) {
    return left.add(right)
}

仍然存在一些想法和问题,即:
1. 我想知道以上是否是实现我目标的最佳方法。
2. 所有方法的签名都应该使用 NumTheObjC 参数类型而不是 NumThe 吗?
3. 我似乎无法弄清楚如何让上面的“a + b”重载运算符返回一个 NumThe 实例而不是 NumTheObjC 实例。
4. 使用 C++ 之类的模板/类型来获取各种重载方法/操作符有没有更有效的方法?

提前感谢您的任何建议/提示!

【问题讨论】:

    标签: objective-c c swift operator-overloading wrapper


    【解决方案1】:

    1.我想知道以上是否是实现我的目标的最佳方法。

    您可能需要一个新的子类NumThe。您可以通过扩展 NumTheObjC 添加新的 init()。请参阅this Apple doc 了解更多信息

    2.所有方法的签名都应该使用 NumTheObjC 参数类型而不是 NumThe 吗?

    如果你使用扩展,那么你不需要改变你的参数类型

    3.我似乎无法弄清楚如何让上面的“a + b”重载运算符返回一个 NumThe 实例而不是 NumTheObjC 实例。

    第 1 点(“扩展”)的解决方案也应该解决这个问题

    4.使用 C++ 之类的模板/类型来获取各种重载方法/操作符是否有更有效的方法?

    我认为这是不可能的。再次查看this Apple docPreprocessor Directives 部分。

    【讨论】:

    • 感谢 Anthony 对扩展机制的引用,我还没有看这个。我仍然面临上面的以下代码(另请参见第 3 项):
      var nt1 = NumThe(12), nt2 = NumThe(45)
      var nt3 = nt1 + nt2
      我想要 nt3是一个 NumThe-instance,而是一个 NumTheObjC 实例。我该如何做到这一点?
    猜你喜欢
    • 2022-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    相关资源
    最近更新 更多