UnsafeMutablePointer<Int8> from String in Swift

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-27 04:07:36

问题


I'm using the dgeev algorithm from the LAPACK implementation in the Accelerate framework to calculate eigenvectors and eigenvalues of a matrix. Sadly the LAPACK functions are not described in the Apple Documentation with a mere link to http://netlib.org/lapack/faq.html included.

If you look it up, you will find that the first two arguments in dgeev are characters signifying whether to calculate eigenvectors or not. In Swift, it is asking for UnsafeMutablePointer<Int8>. When I simply use "N", I get an error. The dgeev function and the error are described in the following screenshot

What should I do to solve this?


回答1:


The "problem" is that the first two parameters are declared as char * and not as const char *, even if the strings are not modified by the function:

int dgeev_(char *__jobvl, char *__jobvr, ...);

is mapped to Swift as

func dgeev_(__jobvl: UnsafeMutablePointer<Int8>, __jobvr: UnsafeMutablePointer<Int8>, ...) -> Int32;

A possible workaround is

let result = "N".withCString { 
    dgeev_(UnsafeMutablePointer($0), UnsafeMutablePointer($0), &N, ...)
}

Inside the block, $0 is a pointer to a NUL-terminated array of char with the UTF-8 representation of the string.


Remark: dgeev_() does not modify the strings pointed to by the first two arguments, so it "should be" declared as

int dgeev_(const char *__jobvl, const char *__jobvr, ...);

which would be mapped to Swift as

func dgeev_(__jobvl: UnsafePointer<Int8>, __jobvr: UnsafePointer<Int8>, ...) -> Int32;

and in that case you could simply call it as

let result = dgeev_("N", "N", &N, ...)

because Swift strings are converted to UnsafePointer<Int8>) automatically, as explained in String value to UnsafePointer<UInt8> function parameter behavior.




回答2:


It is ugly, but you can use:

let unsafePointerOfN = ("N" as NSString).UTF8String
var unsafeMutablePointerOfN: UnsafeMutablePointer<Int8> = UnsafeMutablePointer(unsafePointerOfN)

and use unsafeMutablePointerOfN as a parameter instead of "N".




回答3:


With Swift 4.2 and 5 you can use this similar approach

let str = "string"
let unsafePointer = UnsafeMutablePointer<Int8>(mutating: (str as NSString).utf8String)

You can get the result from unsafePointer.



来源:https://stackoverflow.com/questions/27876179/unsafemutablepointerint8-from-string-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!