C API returns null but optional thinks it's set anyway

I have some Swift code (in Xcode 7.3) that's calling a C function in the GDAL library. It's declared like this:

typedef void *GDALDatasetH;
GDALDatasetH CPL_DLL CPL_STDCALL
GDALOpen( const char *pszFilename, GDALAccess eAccess ) CPL_WARN_UNUSED_RESULT;

I'm calling it with code like this:

class
MyClass
{
    func foo()
    {
        self.dataset = GDALOpen(path, GA_ReadOnly)
    }

    var dataset: GDALDatasetH?
}

But later code

    if let ds = self.dataset
    {
        print("dataset: \(ds)")
    }

outputs this to the console:

    dataset: 0x0000000000000000

This seems very broken.

···

--
Rick Mann
rmann@latencyzero.com

What’s the Swift type signature on GDALOpen? My guess is that it’s
returning a UnsafePointer<Void> or UnsafeMutablePointer<Void> type. Swift
doesn’t currently handle nullability for C pointers (hence the “Unsafe”
prefix). You’ll need to check the value at the pointer’s location manually.

Dan

···

On Fri, Jul 1, 2016 at 2:59 AM, Rick Mann via swift-users < swift-users@swift.org> wrote:

I have some Swift code (in Xcode 7.3) that's calling a C function in the
GDAL library. It's declared like this:

typedef void *GDALDatasetH;
GDALDatasetH CPL_DLL CPL_STDCALL
GDALOpen( const char *pszFilename, GDALAccess eAccess )
CPL_WARN_UNUSED_RESULT;

I'm calling it with code like this:

class
MyClass
{
    func foo()
    {
        self.dataset = GDALOpen(path, GA_ReadOnly)
    }

    var dataset: GDALDatasetH?
}

But later code

    if let ds = self.dataset
    {
        print("dataset: \(ds)")
    }

outputs this to the console:

    dataset: 0x0000000000000000

This seems very broken.

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

What’s the Swift type signature on GDALOpen? My guess is that it’s returning a UnsafePointer<Void> or UnsafeMutablePointer<Void> type. Swift doesn’t currently handle nullability for C pointers (hence the “Unsafe” prefix). You’ll need to check the value at the pointer’s location manually.

It looks like this:

typealias GDALDatasetH = UnsafeMutablePointer<Void>
@warn_unused_result func GDALOpen(pszFilename: UnsafePointer<Int8>, _ eAccess: GDALAccess) -> GDALDatasetH

Thanks for the clarification. It sure seems like Swift could easily check for Unsafe Pointers with value == 0.

···

On Jul 1, 2016, at 05:42 , Dan Loewenherz <dan@lionheartsw.com> wrote:

Dan

On Fri, Jul 1, 2016 at 2:59 AM, Rick Mann via swift-users <swift-users@swift.org> wrote:
I have some Swift code (in Xcode 7.3) that's calling a C function in the GDAL library. It's declared like this:

typedef void *GDALDatasetH;
GDALDatasetH CPL_DLL CPL_STDCALL
GDALOpen( const char *pszFilename, GDALAccess eAccess ) CPL_WARN_UNUSED_RESULT;

I'm calling it with code like this:

class
MyClass
{
    func foo()
    {
        self.dataset = GDALOpen(path, GA_ReadOnly)
    }

    var dataset: GDALDatasetH?
}

But later code

    if let ds = self.dataset
    {
        print("dataset: \(ds)")
    }

outputs this to the console:

    dataset: 0x0000000000000000

This seems very broken.

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
Rick Mann
rmann@latencyzero.com

In Swift 2, pointers are permitted to be `nil` even if they're not `Optional`. Swift 3 changes this, and so this parameter would either return `GDALDatasetH?` or, if it hadn't been audited yet, `GDALDatasetH!`.

···

On Jul 1, 2016, at 1:55 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

typealias GDALDatasetH = UnsafeMutablePointer<Void>
@warn_unused_result func GDALOpen(pszFilename: UnsafePointer<Int8>, _ eAccess: GDALAccess) -> GDALDatasetH

Thanks for the clarification. It sure seems like Swift could easily check for Unsafe Pointers with value == 0.

--
Brent Royal-Gordon
Architechies