数组元素解引用和寻址 - & buffer [index] - 在Swift中工作吗?

时间:2015-09-09 07:54:53

标签: c swift pointers

我正在编写一个Swift应用程序,我需要使用C函数从套接字进行一些网络缓冲。 Swift通过桥接头导入这些函数,它们需要一个缓冲区指针参数。

这两个功能是有效的:

read(Socket s, void *buf, int num);
write(Socket s, const void *buf, int num);

Swift编译器表明这些函数需要UnsafePointer<Void>。我有一些[UInt8]类型可以保存我的可写数据并接受我的可读数据。 Swift编译器不会抱怨我写的内容,但是我相信下面的代码没有按照我在C语法中的预期进行。

这是我的阅读循环:

var index: Int32 = 0    
while index < length {
    var toRead = length - index
    if toRead > bufferSize {
        toRead = bufferSize
    }

    // Read into my buffer ([Int8]), starting at element `hasRead`
    let justRead: Int32 = read(s, &buffer[Int(index)], toRead)
    index += justRead
}

我的写循环:

var index: Int32 = 0
while index < length {
    var toWrite: Int32 = length - index
    if toWrite > bufferSize {
        toWrite = bufferSize
    }

    // Write from my buffer ([Int8]), starting at element `index`
    let wrote = write(s, &buffer[Int(index)], toWrite)
    index += wrote
}

我的问题是:&buffer[Int(index)]是否是在这种情况下传递(可变)数组的正确方法? (即,它正在做我期望C用该语法做的事情 - 获取索引的地址和数组字节的第13个元素)。如果没有,我如何将[UInt8]适当地传递给桥接C函数?

2 个答案:

答案 0 :(得分:2)

我建议小心使用baseAddress。目前还不清楚从文档中保证做什么。当然,它可以用来修改数组的单个元素,但是我不认为你应该依赖指针算法这个指针(所以你不应该把它传递给像这样的函数)。

然而,您可以/应该使用的是withUnsafeMutableBufferPointer() (apparently missing from docs currently)(或非可变版本)。这可以保证将提供的闭包与UnsafeMutableBufferPointer一起调用到可用于读取和写入数组的连续存储。您可能希望使用其stockName in someFullString

(另请注意,除了Array之外,Swift还有一个ContiguousArray,其存储保证是连续的,因此您可能会看到比Array更好的性能,因为您知道无论如何都会要求它连续的缓冲区但是不要在这里做太多关于性能的假设 - 它没有很好的记录!我怀疑你在实践中需要使用ContiguousArray。)

答案 1 :(得分:1)

你可以:

<plugins>
...
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <recompileMode>incremental</recompileMode>
                    <args>
                        <arg>-target:jvm-1.7</arg>
                    </args>
                    <javacArgs>
                        <javacArg>-source</javacArg>
                        <javacArg>1.7</javacArg>
                        <javacArg>-target</javacArg>
                        <javacArg>1.7</javacArg>
                    </javacArgs>
                </configuration>
                <executions>
                    <execution>
                        <id>scala-compile</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
</plugins>

我认为read(s, &buffer + Int(index), toRead) 并不安全,如this QA

中所述