Я понимаю, что существует миллион вариаций вопроса «как мне конвертировать char[]
/ char*
в стремительный укус» и их обратный вопрос, на который все были заданы и даны ответы.
Я этого не спрашиваю.
Все, что я хочу сделать в Swift, - это просто передать адрес массива C char
(полученный с помощью функции C) аргументу указателя C char*
другой функции C.
В частности, я пытаюсь скопировать следующий код C, где адрес массива char
, содержащийся в поле stat.f_mntonname
, передается в качестве первого параметра вызова getattrlist(const char*, ...)
:
// Get volume stat
const char* path = ...;
struct statfs volStat;
if (statfs(path,&volStat)==-1) { error }
// statfs has the mount point of the volume; use that to get attributes
struct attrlist request;
// ... set up request here
struct volAttrs {
// ... response values
}
if (getattrlist(volStat.f_mntonname,&request,&volAttrs,sizeof(volAttrs),FSOPT_NOFOLLOW)==-1) { error }
Проблема, похоже, заключается в том, что Swift интерпретирует поле stat.f_mntonname
не как массив, а как кортеж, содержащий MAXPATHLEN
количество Int8
значений; другими словами, (Int8,Int8,Int8,Int8,Int8,...,Int8)
.
После долгих раздумий в интернете, я смог найти этот обходной путь:
var volStat = statfs()
guard statfs(fileURL.path, &volStat) != -1 else {
ErrorExit(cause: "statfs")
}
var attrRequest = attrlist()
// set up getattrlist request ...
var attrs = XtraVolumeAttrs()
guard getattrlist(UnsafeRawPointer(&volStat.f_mntonname.0).bindMemory(to: CChar.self, capacity: Int(MAXPATHLEN)),
&attrRequest,
&attrs,
MemoryLayout<XtraVolumeAttrs>.size,
UInt32(FSOPT_NOFOLLOW)) != -1 else {
ErrorExit(cause: "getattrlist")
}
Таким образом, магия UnsafeRawPointer(&volStat.f_mntonname.0).bindMemory(to: CChar.self, capacity: Int(MAXPATHLEN)
, кажется, выполняет задачу преобразования массива char[MAXPATHLEN]
в char*
, но мальчик это уродлив, не интуитивен, и - если я полностью честен - я даже не уверен, что это правильно (кроме факта, что код работает).
Я чувствую, что должен быть лучший способ, и я надеялся, что кто-то опубликует его.