Opened 8 years ago

Last modified 5 years ago

#6295 closed enhancement

Provide an interface like GDALOpenEx that does not void* cast the results. — at Version 1

Reported by: Kurt Schwehr Owned by: Kurt Schwehr
Priority: normal Milestone: closed_because_of_github_migration
Component: default Version: svn-trunk
Severity: major Keywords:
Cc:

Description (last modified by Kurt Schwehr)

Using GDALDatasetH as the return type for C++ totally short circuits the C++ compiler's ability to do checking and makes for much more complicated code.

GDALDatasetH CPL_STDCALL GDALOpenEx( const char* pszFilename,
                                 unsigned int nOpenFlags,
                                 const char* const* papszAllowedDrivers,
                                 const char* const* papszOpenOptions,
                                 const char* const* papszSiblingFiles )
{
  // Implementation
}

Would become: (Is there a better name than GDALOpenEx2?)

GDALDataset CPL_STDCALL *GDALOpenEx2( const char* pszFilename,
                                      unsigned int nOpenFlags,
                                      const char* const* papszAllowedDrivers,
                                      const char* const* papszOpenOptions,
                                      const char* const* papszSiblingFiles )
{
  GDALDataset *poDS = NULL;

  // Implementation.

  return poDS;
}

GDALDatasetH CPL_STDCALL GDALOpenEx( const char* pszFilename,
                                 unsigned int nOpenFlags,
                                 const char* const* papszAllowedDrivers,
                                 const char* const* papszOpenOptions,
                                 const char* const* papszSiblingFiles )
{
    return reinterpret_cast<GDALDatasetH> GDALOpenEx2(
        pszFilename, nOpenFlags, papszAllowedDrivers, papszOpenOptions,
        papszSiblingFiles );
}

With this change, then I can just do this:

// C++11 or newer.
void Worker()
{
  unique_ptr<GDALDataset> poDS(
      GDALOpenEx2("foo.tif", GDAL_OF_RASTER, nullptr, nullptr, nullptr));

  // work work work.

  if (error condition)
    return;  // No need to worry about if poDS is valid.

  // work work work.

  return;  // No need to worry about poDS cleanup.
}

Instead, I need to do something like this:

// Signature of GDALClose.  Sadly, GDALDatasetH is a void *.
typedef void (*GDALDatasetDeleter)(GDALDatasetH);

void Worker()
{
  unique_ptr<GDALDataset, GDALDatasetDeleter> src(
      static_cast<GDALDataset *>(GDALOpenEx(
          "foo.tif", GDAL_OF_READONLY, nullptr, nullptr, nullptr)),
        GDALClose);

  // work work work.

  if (error condition)
    return;  // No need to worry about if poDS is valid.

  // work work work.

  return;  // No need to worry about poDS cleanup.  GDALClose() called.
}

Or if no sharing and no surprises are added to GDALDataset:

  unique_ptr<GDALDataset> src(
      static_cast<GDALDataset *>(GDALOpenEx(
          "foo.tif", GDAL_OF_READONLY, nullptr, nullptr, nullptr)));

The one issue with this: It does not work with shared/reference counted GDALDatasets.

Thoughts?

Change History (1)

comment:1 by Kurt Schwehr, 8 years ago

Description: modified (diff)
Status: newassigned
Note: See TracTickets for help on using tickets.