I have a function written in Swift that I want to call from Rust. I've tried exposing it through Objective-C, however I continue to get errors from ld
saying it can't find _foo
. The Rust project is linked to the Swift project by compiling the Rust project as a staticlib.
#pragma once
#include <stdint.h>
uint8_t foo_bridge(uint8_t);
#import <Foundation/Foundation.h>
#import <Foo-Swift.h>
uint8_t foo_bridge(uint8_t byte) {
return foo(byte);
}
public func foo(byte: UInt8) -> UInt8 {
return byte * 2
}
extern "C" {
pub fn foo_bridge(byte: u8) -> u8;
}
#import "foo.h"
[package]
name = "foo"
version = "0.1.0"
[lib]
name = "foo"
crate-type = ["staticlib"]
The issue here is attempting to call a bare Swift function from Objective-C, which isn't supported.
If you check the Foo-Swift.h
header you'll find that the foo()
function isn't present, which indicates that the symbol for it, _foo
, won't be available at runtime either.
The solution is to put the foo()
function inside something that can be called from Objective-C, like a class deriving from NSObject:
class Foo: NSObject {
class func foo(byte: UInt8) -> UInt8 {
return byte * 2
}
}
Once you do that, you'll find the Foo-Swift.h
header now has an interface for it:
@interface Foo : NSObject
+ (uint8_t)fooWithByte:(uint8_t)byte;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
Since we know it's available from Objective-C now, we can call it like this:
uint8_t foo_bridge(uint8_t byte) {
return [Foo fooWithByte:byte];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With