I have a Class defined in C++, I want to pass the instance of class from C++ to Swift as a reference type. By default swift maps C++ classes as value types but we can change this behavior by using SWIFT_IMMORTAL_REFERENCE annotation mentioned here. The example mentioned here is of Singelton class but I have a usecase where i require more than one instance.
Cpp Class Skeleton.
class Cpp {
public:
void Print () noexcept;
void SetValue (int pValue) noexcept;
// Method which is Invoked by Swift.
static Cpp& ReturnObj () noexcept;
private:
int vValue;
} SWIFT_IMMORTAL_REFERENCE;
Definition of Return Obj
Cpp&
Cpp::ReturnObj () noexcept {
static Cpp obj;
return obj;
}
Swift Co
var obj : Cpp = Cpp.ReturnObj()
withUnsafeBytes(of: &obj) {(pointer : UnsafeRawBufferPointer) in
print (pointer)
print (pointer.baseAddress!)
}
Output
Address Printed by C++ 0x100008000
Address Printed by Swift 0x00007ff7bfeff108
So from the above observation copy is passed.
How to do pass by reference then?
Again, you’re missing really fundamental aspects of how Swift works. In your example, withUnsafeBytes(of: &obj)
doesn’t yield the address of the object, it yields the address of the pointer. And that may not even be the actual pointer, because &
is free to copy in and then copy out. I cover that in detail in The Peril of the Ampersand, which I linked to in my response on your previous thread.
Consider this code:
class MyClass {}
var o1 = MyClass()
var o2 = o1
withUnsafeBytes(of: &o1) { p in
print(p.baseAddress!) // 0x00000001000084f8
withUnsafeBytes(of: &o2) { p in
print(p.baseAddress!) // 0x0000000100008500
}
}
The addresses are different because they’re the addresses of o1
and o2
(or a copy thereof), not the address of the object itself.
The standard way to get the ‘address’ of an object is via ObjectIdentifier
:
class MyClass {}
let o1 = MyClass()
let o2 = o1
print(ObjectIdentifier(o1)) // ObjectIdentifier(0x00006000006a00c0)
print(ObjectIdentifier(o2)) // ObjectIdentifier(0x00006000006a00c0)
ps I’m happy to keep answering your questions — I think it’s great to have an excuse to populate DevForums with a corpus of knowledge like this — but it might be more efficient for you to review some of the resources I’ve been pointing you at. The Peril of the Ampersand has some great talks you really need to watch. Additionally, I think you’d get a lot of value out of the Swift for C++ Practitioners series.
https://www.douggregor.net
The author is:
-
One of the architects of Swift
-
And has an extensive C++ background
That makes him very well qualified to explain this stuff.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"