In my experiments with the cxx-interop and the latest toolchain (January 28) I tried to expose a Swift function to c++. I found the @_expose attribute is available in this release and compiled an ultra simple Swift library named "MySwiftLib":
// swift-tools-version: 5.7
import PackageDescription
let package = Package(
name: "SwiftCXXInteropExample",
platforms: [
.macOS(.v12),
],
products: [
.library(name: "MySwiftLib", type: .dynamic, targets: ["MySwiftLib"])
],
dependencies: [],
targets: [
.target(name: "MySwiftLib", swiftSettings: [.unsafeFlags(["-enable-experimental-cxx-interop"])])
]
)
// Ultra simple Swift library
// file.swift
import Foundation
@_expose(Cxx, "my_exposed_swift_add")
func my_swift_add(a: Int64, b: Int64) -> Int64 {
return a + b
}
The swift build ran ok and I expected to find the "my_swift_add" function signature in the generated MySwiftLib-Swift.h header and the corresponding c++ symbol in the libMySwiftLib.dylib.
The MySwiftLib-Swift.h contain the library namespace MySwiftLib but not the function signature.
namespace MySwiftLib __attribute__((swift_private)) SWIFT_SYMBOL_MODULE("MySwiftLib") {
} // namespace MySwiftLib
The dylib seems to include only the Swift function mangled signature.
admin@mbam1 debug % nm -gU libMySwiftlib.dylib
0000000000003118 T _$s10MySwiftLib12my_swift_add1a1bs5Int64VAF_AFtF
admin@mbam1
Whatever I use the @_expose attribute or not make no difference.
Is I miss something ?
Thanks
allevato
(Tony Allevato)
2
What happens if you declare the function public? If C++ interop symbol visibility is anything like Obj-C interop (I haven't verified this myself), a declaration needs to be public to be generated into the header file.
Thanks Tony for the hint, public make a difference. The function now appear in the header !
namespace MySwiftLib __attribute__((swift_private)) SWIFT_SYMBOL_MODULE("MySwiftLib") {
inline int64_t my_exposed_swift_add(int64_t a, int64_t b) noexcept SWIFT_SYMBOL("s:10MySwiftLib12my_swift_add1a1bs5Int64VAF_AFtF") SWIFT_WARN_UNUSED_RESULT {
return _impl::$s10MySwiftLib12my_swift_add1a1bs5Int64VAF_AFtF(a, b);
}
It seem the @_expose attribute is required even if we don't want to expose a different function name.
Now I can go further and try to link and call the function from c++ side.
Thanks !
2 Likes
For those who might be interested. I finally managed to call my simple Swift function from C++ using the lastest toolchain.
#include <iostream>
#include <stdint.h>
#include "MySwiftLib-Swift.h"
int main(int argc, const char * argv[]) {
int64_t result = MySwiftLib::my_exposed_swift_add(2, 7);
std::cout << "Hello, World! " << result << "\n";
return 0;
}
// output
// Hello, World! 9
A big thank you to the Swift team and the cxx-interop group !!
The upcoming possibilities and benefits from a Swift <-> C++ interop is simply fantastic and opens up a universe of possibilities !!
Will we be able to use for production when Swift 5.8 release ?
1 Like