【问题标题】:How to call a Swift function in Rust?如何在 Rust 中调用 Swift 函数?
【发布时间】:2017-03-20 12:00:05
【问题描述】:

我有一个用 Swift 编写的函数,我想从 Rust 调用它。我尝试通过Objective-C 公开它,但是我继续从ld 收到错误,说它找不到_foo。 Rust 项目通过将 Rust 项目编译为静态库来链接到 Swift 项目。

foo.h

#pragma once

#include <stdint.h>

uint8_t foo_bridge(uint8_t);

foo.m

#import <Foundation/Foundation.h>
#import <Foo-Swift.h>

uint8_t foo_bridge(uint8_t byte) {
    return foo(byte);
}

bar.swift

public func foo(byte: UInt8) -> UInt8 {
    return byte * 2
}

src/lib.rs

extern "C" {
    pub fn foo_bridge(byte: u8) -> u8;
}

Bar-Bridging-Header.h

#import "foo.h"

Cargo.toml

[package]
name = "foo"
version = "0.1.0"

[lib]
name = "foo"
crate-type = ["staticlib"]

【问题讨论】:

  • 您需要提供更多信息。这是一个链接器错误,但您没有指定有关如何将 swift 项目链接到 Rust 项目的任何信息。
  • @ker 已更新。我通过将 rust 项目编译为静态库来链接。
  • 所以我误解了......你在你的 swift 项目中链接 Rust 项目?你是如何快速做到这一点的?请发布完整的命令行。我非常不清楚您将什么链接到错误发生的位置和方式。
  • 完整的命令行?这是在 XCode 中,我刚刚创建了一个 Objective-C 桥接头,并且工作正常。你可以在这里阅读更多它是如何工作的:bignerdranch.com/blog/building-an-ios-app-in-rust-part-1

标签: objective-c swift rust ffi


【解决方案1】:

这里的问题是尝试从 Objective-C 调用一个裸 Swift 函数,这是不受支持的。

如果您检查 Foo-Swift.h 标头,您会发现 foo() 函数不存在,这表明它的符号 _foo 在运行时也不可用。

解决方案是将foo() 函数放在可以从Objective-C 调用的东西中,例如从NSObject 派生的类:

class Foo: NSObject {
    class func foo(byte: UInt8) -> UInt8 {
        return byte * 2
    }
}

一旦你这样做了,你会发现Foo-Swift.h 标头现在有了一个接口:

@interface Foo : NSObject
+ (uint8_t)fooWithByte:(uint8_t)byte;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

既然我们知道它现在可以从 Objective-C 中获得,我们可以这样称呼它:

uint8_t foo_bridge(uint8_t byte) {
    return [Foo fooWithByte:byte];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多