Returning Typed Pointer From Swift to C++

I have a struct defined in Swift, i want to pass it's instance pointer from swift to C++. When I am trying to directly return Typed Pointer from Swift Function to C++, the function doesn't get expose to C++.

Code which i have tried.

// Defined Structure 

public struct MyStruct {
    
    public init (_ pValue : Int) {
        
        uValue = pValue
    }
    public var uValue : Int
}

var my_struct = MyStruct(20)

// Function which returns Struct Pointer to C++
// When I return typed pointer this function doesn't get exposed to C++
public func PassStructPointer () -> UnsafeMutablePointer<MyStruct> {
    
    withUnsafeMutablePointer(to: &my_struct) { pointer in
        
        return pointer
    }
}

But when I pass UnsafeRawMutablePointer instead of type pointer then the function does get expose to C++

var my_struct = MyStruct(20)

// This get expose to C++.
public func PassStructPointer () -> UnsafeMutableRawPointer {
    
    return withUnsafeMutableBytes(of: &my_struct) { pointer in
        return pointer.baseAddress!
    }
}

Can we not pass typed pointer of the types defined by us?

Answered by DTS Engineer in 803095022

The code you’ve posted suggest a serious misunderstanding of how pointers work in Swift. Swift can work with C-style pointers but those are not its natural model. Rather, Swift works in terms of value types (structs and enums) and reference types (classes, actors, and closures).

When you use C (or C++) patterns in Swift, you really need to understand Swift’s rules for handling pointers. If you don’t, you will run into problems, because those rules don’t match the intuition you have from working with C-based languages. For example, this code:

func PassStructPointer () -> UnsafeMutablePointer<MyStruct> {
    withUnsafeMutablePointer(to: &my_struct) { pointer in
        return pointer
    }
}

is not valid Swift because you are not allowed to ‘escape’ the pointer value from the closure. The docs for withUnsafeMutablePointer() make that clear:

The pointer argument is valid only for the duration of the function’s execution.

In some cases Swift is able to warn you about this. In this particular case it’s not )-:

There are a couple of really great WWDC talks that should help you get a better handle on this:

You might also want to have a read of The Peril of the Ampersand, which covers other cases where your C++ intuition will likely lead you astray.

I realise that this doesn’t answer the actual question your asked, but I think your life will be easier if you try to use Swift as it was intended to be used.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Yes, UnsafeMutableRawPointer is a way to do it. But look at some other of your post for a discussion about the issues doing so.

The code you’ve posted suggest a serious misunderstanding of how pointers work in Swift. Swift can work with C-style pointers but those are not its natural model. Rather, Swift works in terms of value types (structs and enums) and reference types (classes, actors, and closures).

When you use C (or C++) patterns in Swift, you really need to understand Swift’s rules for handling pointers. If you don’t, you will run into problems, because those rules don’t match the intuition you have from working with C-based languages. For example, this code:

func PassStructPointer () -> UnsafeMutablePointer<MyStruct> {
    withUnsafeMutablePointer(to: &my_struct) { pointer in
        return pointer
    }
}

is not valid Swift because you are not allowed to ‘escape’ the pointer value from the closure. The docs for withUnsafeMutablePointer() make that clear:

The pointer argument is valid only for the duration of the function’s execution.

In some cases Swift is able to warn you about this. In this particular case it’s not )-:

There are a couple of really great WWDC talks that should help you get a better handle on this:

You might also want to have a read of The Peril of the Ampersand, which covers other cases where your C++ intuition will likely lead you astray.

I realise that this doesn’t answer the actual question your asked, but I think your life will be easier if you try to use Swift as it was intended to be used.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Returning Typed Pointer From Swift to C++
 
 
Q