[swift-dev] Returning more than two scalars from C code

Joe Groff jgroff at apple.com
Tue Mar 22 11:05:06 CDT 2016


> On Mar 22, 2016, at 5:57 AM, Bryan Chan via swift-dev <swift-dev at swift.org> wrote:
> 
> I tried to google for an answer but couldn't find anything. What is the correct way to do the following on Linux?
> 
> @_silgen_name("foo")
> func foo(theInt: UInt)
> -> (a: UInt, b: UInt, c: UInt)
> 
> var (d, e, f) = foo(aNum)
> 
> Where foo is:
> 
> typedef struct {
> long a;
> long b;
> long c;
> } Tuple;
> 
> extern "C" {
> Tuple foo(int i) {
> return Tuple{ i, i, i };
> }
> }
> 
> Currently, the call to foo crashes because foo wants to return the tuple indirectly, but the Swift call expects the three scalar return values in registers. This example is a generalization of runtime functions such as swift_class_getInstanceExtents, which happens to work because it only returns two scalars in RAX and RDX, which is supported by Clang. But my tests show that three-scalar tuples/structs will cause problems. On architectures where Clang only supports one scalar return value, the problem is worse.
> 
> Am I doing something wrong or is there already a way to deal with this (e.g. annotation in Swift code to make it obey C ABI, or vice versa)?
> 

Don't use @_silgen_name. If you want to use a C API from Swift, define a Clang module for its headers, and import the module. See http://clang.llvm.org/docs/Modules.html for documentation on Clang module maps.

-Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160322/7b0d4175/attachment.html>


More information about the swift-dev mailing list