I have a problem with Swift 2, I'm not able to convert this part of my code:
let intTran = UnsafeMutablePointer<Int>(bitPattern: -1)
let tranPointer = COpaquePointer(intTran)
let transient = CFunctionPointer<((UnsafeMutablePointer<()>) -> Void)>(tranPointer)
I receive this error:
'CFunctionPointer' is unavailable: use a function type '#convention(c) (T) -> U'
I am trying to change it for this way:
let intTran = UnsafeMutablePointer<Int>(bitPattern: -1)
let tranPointer = COpaquePointer(intTran)
typealias transient2 = #convention(c) (UnsafeMutablePointer<()>) -> Void
But I am not able to use transient2 and I am not sure why.
Than you
I have been playing around with your code inside a Swift playground and noticed that this piece of code (your substitution to the original one) fails due to the bitPattern when it's set to -1 (notice that I've been getting a runtime exception - not a compiler error). When I replaced it with something appropriate (e.g. with 1, as bitPattern must represent a valid address inside you virtual address space and, as implied, must be a non-negative integer) it worked out. I managed to make it up and running with the following code:
import Foundation
let intTran = UnsafeMutablePointer<Int>(bitPattern: 1)
let tranPointer = COpaquePointer(intTran)
typealias transient2 = #convention(c) (UnsafeMutablePointer<()>) -> Void
let abc: transient2? = nil
Good luck, hope this solves your problem.
Related
I am very green with Xcode (apologize in advance). Trying to bring some old code to life. Getting the following with trying to move to Swift 5.
withUnsafeMutableBytes' is deprecated: use withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R instead
Goal: All I need to do is modify the code appropriately and be done.
I have looked at other Stack Overflow messages, searched various articles, experimented with different things, but can't quickly determine what needs to change. I am sure the solution is super simple for someone that knows more.
var responseData = Data(count: Int(responseDataLength))
_ = responseData.withUnsafeMutableBytes
{
mfError = MFMediaIDResponse_GetAsString(mfMediaIdResponsePtr.pointee, MFString($0), responseDataLength)
}
Here is my example, when refreshing old code of withUnsafeMutableBytes
hope it helps
The old one:
_ = data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) in
memcpy((ioData.pointee.mBuffers.mData?.assumingMemoryBound(to: UInt8.self))!, bytes, dataCount)
}
The new one:
_ = data.withUnsafeMutableBytes { (rawMutableBufferPointer) in
let bufferPointer = rawMutableBufferPointer.bindMemory(to: UInt8.self)
if let address = bufferPointer.baseAddress{
memcpy((ioData.pointee.mBuffers.mData?.assumingMemoryBound(to: UInt8.self))!, address, dataCount)
}
}
Explains:
use UnsafeMutablePointer<ContentType>, you get an unsafeMutablePointer in its closure.
To access to its memory, so need to typed it with bindMemory,
more details on Apple Pointer Doc
I recently found that the code below ends up with hash collision.
FYI, I'm using XCode 9.4.1 (9F2000), which uses Swift 4.1.2
import Foundation
let lhs = "あいうえおあいう21あいうえ"
let rhs = "あいうえおあいう22あいうえ"
let percentEncodedLhs = lhs.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
let percentEncodedRhs = rhs.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
let lhsHashValue = lhs.hashValue
let rhsHashValue = rhs.hashValue
let lhsPercentHashValue = percentEncodedLhs.hashValue
let rhsPercentHashValue = percentEncodedRhs.hashValue
print(lhsHashValue == rhsHashValue)
print(lhsPercentHashValue == rhsPercentHashValue)
/*
Output:
false
true
*/
I know that hash collision can happen in some circumstance, but I couldn't find how Swift calculates hashValue for String.
For example, Java calculates hashCode of String like:
https://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode()
Is there any official explanation or maybe some assumptions?
but I couldn't find how Swift calculates hashValue for String
Why couldn’t you? Swift is open source. If you are interested, read the source.
https://github.com/apple/swift/blob/111499d2bfc58dc12fcb9cd1ce1dda7978c995b7/stdlib/public/core/StringHashable.swift
I'm using the MapBox navigation framework that hasn't quite been updated to Swift 4. I have one 'subscript' error that I can't quite get around. Here's the code. I'd really appreciate any help. Thank you.
private func extractNextChunk(_ encodedString: inout String.UnicodeScalarView) throws -> String {
var currentIndex = encodedString.startIndex
while currentIndex != encodedString.endIndex {
let currentCharacterValue = Int32(encodedString[currentIndex].value)
if isSeparator(currentCharacterValue) {
let extractedScalars = encodedString[encodedString.startIndex...currentIndex]
encodedString = encodedString[encodedString.index(after: currentIndex)..<encodedString.endIndex]
return String(extractedScalars)
}
currentIndex = encodedString.index(after: currentIndex)
}
throw PolylineError.chunkExtractingError
}
The error message is misleading. The real problem is that subscripting
a String.UnicodeScalarView with a range returns a String.UnicodeScalarView.SubSequence, so you cannot assign that back to
encodedString.
One solution would be to create a String.UnicodeScalarView
from the subsequence:
encodedString = String.UnicodeScalarView(encodedString[encodedString.index(after: currentIndex)...])
Alternatively (and perhaps simpler) go the other way around and
remove the initial part of encodedString instead:
encodedString.removeSubrange(...currentIndex)
In either case, you can take use "one-sided ranges", compare
SE-0172
This question and answer describe how to read data from a Mach-O section with Objective-C on modern OS X/macOS versions: Crash reading bytes from getsectbyname
The described answer works. I'm trying to implement the same thing with Swift. I can't make it work.
I have the following in "Other linker flags": -Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r.
This Swift code gets me the a pointer to the embedded data, until I try to run the code outside Xcode and ASLR breaks it:
var size: UInt = 0
let _localizationSection = getsectdata(
"__LOCALIZATIONS",
"__base",
&size)
To get around the ASLR problem, according to the above question and answer, and based on my own testing, I should be using getsectiondata instead. It works great in Objective-C, but I'm having no luck in Swift. The following is the only thing I've managed to get past the compiler, but it returns nil:
var size: UInt = 0
var header = _mh_execute_header
let localizationSection = getsectiondata(
&header,
"__LOCALIZATIONS",
"__base",
&size)
Is taking a copy of _mh_execute_header the problem and is there any way to avoid it? I need an UnsafePointer<mach_header_64>, but using &_mh_execute_header as the first parameter to getsectiondata causes a compilation error.
I'm using Swift 3.0, and running my code on macOS 10.12.
The difference between the linked-to Objective-C code
void *ptr = getsectiondata(&_mh_execute_header, ...);
and your Swift translation
var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)
is that the latter passes the address of a copy of the global
_mh_execute_header variable to the function, and apparently that
is not accepted. If you modify the Objective-C code to
struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);
then it fails as well (and actually crashed in my test).
Now the problem is that _mh_execute_header is exposed to Swift
as a constant:
public let _mh_execute_header: mach_header_64
and one cannot take the address of a constant in Swift. One possible
workaround is to define
#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;
in the bridging header file, and then use it as
let localizationSection = getsectiondata(mhExecHeaderPtr, ...)
in Swift.
Another option is to lookup the symbol via dlopen/dlsym
import MachO
if let handle = dlopen(nil, RTLD_LAZY) {
defer { dlclose(handle) }
if let ptr = dlsym(handle, MH_EXECUTE_SYM) {
let mhExecHeaderPtr = ptr.assumingMemoryBound(to: mach_header_64.self)
var size: UInt = 0
let localizationSection = getsectiondata(
mhExecHeaderPtr,
"__LOCALIZATIONS",
"__base",
&size)
// ...
}
}
I'm using a type from a different module, let's call it OtherModule.MyType,
This code:
var a = [OtherModule.MyType]()
will produce an error invalid use of '()' to call a value of non-function type '[MyType.Type]'
This code won't:
var ax = [OtherModule.MyType]
But I believe ax is not an array any more, since this code
ax.append(OtherModule.MyType())
will cause an error Cannot invoke 'append' with an argument list of '(MyType)'
So I wonder what ax really is?
Besides, this code works fine:
var ay = Array<OtherModule.MyType>()
ay.append(OtherModule.MyType())
UPDATE:
I'm using swift 1.2 with Xcode 6.3
For some reason best known to the Swift team (modules are very scantly documented), Module.Thing behaves differently to Thing.
While Int is just a type name:
let i: Int = 1 // fine
// not fine, "expected member name or constructor call after type name"
let j = Int
Swift.Int can be both:
// used as a type name
let k: Swift.Int = 1
let t = Swift.Int.self
// but also used as a value
let x = Swift.Int
// equivalent to this
let y = Int.self
toString(x) == toString(y) // true
Under some uses it only wants to be a value, not a type name though. Hence this works:
// a will be of type [Int.Type], initialized with an array
// literal of 1 element, the Int metatype
let a = [Swift.Int]
But trying to use it as a type name in this context fails: [Swift.Int]() is no more valid than writing [1]() or let strs = ["fred"]; strs().
This behaviour seems a little arbitrary, and may even be a bug/unintentional.
Since the only way in which Swift.Int can be used in this context:
Array<Swift.Int>()
is as a type not a value (since only types can go between the angle brackets), it kind of makes sense that this works while the more ambiguous array literal syntax behaves differently.