5

Is it possible to convert a Swift class into C void* pointer?

// swift class
 class MyClass {

 }

var myClass = MyClass()
var p: UnsafeMutablePointer<Void> = myClass //<- failed

//c function 
void someSwiftClass(void *context);

Thanks

CocoaUser
  • 1,361
  • 1
  • 15
  • 30
  • 2
    that question does not make any sense. a void * is just a memory address with no assumption as to what is at that memory address. You can cast any pointer to a void *, but there is no conversion as void has no form to convert to. – Rob May 24 '15 at 02:04

3 Answers3

4

I had similar problem, you can convert this as below.

var myClass = MyClass()

var classPtr = unsafeBitCast(myClass, UnsafePointer<Void>.self)    

and your function,

func someSwiftClass(voidPointer: UnsafeMutablePointer<Void>) {

}

If you want to declare constant pointer use UnsafePointer<T> and when your pointer is not constant use UnsafeMutablePointer<T>

In C constant pointer - const int *myCpointer

Corresponding swift pointer - let mySwiftPointer: UnsafePointer<Int32>

Amit89
  • 3,000
  • 1
  • 19
  • 27
  • Thanks a lot. but "void someSwiftClass" is C function format and "(voidPointer: UnsafeMutablePointer)" is swift function format – CocoaUser May 24 '15 at 04:58
1

This works:

var p: UnsafeMutablePointer<Void> =
    UnsafeMutablePointer(Unmanaged.passUnretained(myClass).toOpaque())
newacct
  • 119,665
  • 29
  • 163
  • 224
  • Thanks. This works for me (so far) where I am calling a swift class non-static method from a C++ thread via Objective C using dispatch_async(dispatch_get_main_queue(), ...). – user3717478 Sep 24 '15 at 20:41
0

I have done some testing using Swift 2. The behavior in Swift 2 may be different than it was in earlier Swift versions, but here is what I found.

The solutions suggested by Amit89 and newacct will compile, but there may be problems using the instance of MyClass in C code. Something like this

someSwiftClass(&myClass)

will also compile just fine, but with the same problem.

I don't know the context of the original question, but let me guess that the C code will do something with the void * passed to someSwiftClass(), so there is an instance of some C type that the pointer is assumed to point to. As my experience shows, in this case it is safer to import the C data type, most likely a struct, into Swift and either use that imported type throughout your Swift code or use some wrapper Swift class/struct. You can write the wrapper to wrap an UnsafeMutablePointer, in which case the changes made to the data in Swift code will be visible in C!

Please see this question for more details: Swift converts C's uint64_t different than it uses its own UInt64 type

I also have a blog post that you might find useful: http://www.swiftprogrammer.info/callback_void.html

Community
  • 1
  • 1
Anatoli P
  • 4,791
  • 1
  • 18
  • 22