如何在Rust中调用Swift函数?

7

我有一个用Swift编写的函数,我想从Rust中调用它。我尝试通过Objective-C公开它,但是我一直收到来自ld的错误,说它找不到_foo。通过将Rust项目编译为staticlib将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"]

1
你需要提供更多信息。这是一个链接器错误,但你没有指定任何关于如何将 Swift 项目链接到 Rust 项目的信息。 - oli_obk
@ker 已更新。我通过将 Rust 项目编译为静态库来进行链接。 - XAMPPRocky
所以我误解了...你是在你的swift项目中链接Rust项目?你是如何在Swift中做到这一点的?请发布完整的命令行。我不清楚你在链接什么和错误出现的方式。 - oli_obk
完整的命令行?这是在XCode中,我刚刚创建了一个Objective-C桥接头文件,它很好地运行。您可以在此处阅读有关其工作原理的更多信息:https://www.bignerdranch.com/blog/building-an-ios-app-in-rust-part-1/ - XAMPPRocky
1个回答

8
这里的问题是试图从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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接