Opened 8 years ago

Closed 5 years ago

#6295 closed enhancement (wontfix)

Provide an interface like GDALOpenEx that does not void* cast the results.

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 (3)

comment:1 by Kurt Schwehr, 8 years ago

Description: modified (diff)
Status: newassigned

comment:2 by Even Rouault, 8 years ago

Milestone: 2.1.0
Type: defectenhancement

Unmilestoning.

comment:3 by Even Rouault, 5 years ago

Milestone: closed_because_of_github_migration
Resolution: wontfix
Status: assignedclosed

This ticket has been automatically closed because Trac is no longer used for GDAL bug tracking, since the project has migrated to GitHub. If you believe this ticket is still valid, you may file it to https://github.com/OSGeo/gdal/issues if it is not already reported there.

Note: See TracTickets for help on using tickets.