Thread overview
Trouble in converting C code to D
Apr 12, 2015
Suliman
Apr 12, 2015
Stefan Koch
Apr 12, 2015
Suliman
Apr 12, 2015
Jacob Carlborg
Apr 12, 2015
Suliman
Apr 12, 2015
Suliman
Apr 12, 2015
Jacob Carlborg
Apr 12, 2015
Jacob Carlborg
April 12, 2015
So I got GDAL binding work. And now I need to understand how to translate C code to D.

Here is simple tutorial: http://www.gdal.org/gdal_tutorial.html If I right understand it's easier to take C, than C++ code example.

Now I am trying to get very simple example work. My code is:

  string fileTiff = `D:\code\RSM2DOC\data-example\03022014_101_022731_09_10_Rostov.tif`;
  if (!fileTiff.exists)
    writeln("Tiff file do not exists");

  GDALDatasetH hDataset = GDALOpen( toStringz(fileTiff), GDALAccess.GA_ReadOnly );

  GDALDriverH  hDriver;
  hDriver = GDALGetDatasetDriver(hDataset);

  double adfGeoTransform[6];

  if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
  {
    writeln(adfGeoTransform[1]);
  }


function (void*, double*) is not callable using argument types (void*, double[6])

I can't understand why this error is rise up. It's look like 1-to-1 with C code.

Also I can't understand at what moment adfGeoTransform get in it value.
April 12, 2015
Do have you extern(C) everywhere ?

April 12, 2015
On Sunday, 12 April 2015 at 09:36:54 UTC, Stefan Koch wrote:
> Do have you extern(C) everywhere ?

Yes, at binding file. Here is a lot of string like:
extern(C) CPLErr   GDALGetGeoTransform( GDALDatasetH, double* );

April 12, 2015
On 2015-04-12 11:19, Suliman wrote:
> So I got GDAL binding work. And now I need to understand how to
> translate C code to D.
>
> Here is simple tutorial: http://www.gdal.org/gdal_tutorial.html If I
> right understand it's easier to take C, than C++ code example.
>
> Now I am trying to get very simple example work. My code is:
>
>    string fileTiff =
> `D:\code\RSM2DOC\data-example\03022014_101_022731_09_10_Rostov.tif`;
>    if (!fileTiff.exists)
>      writeln("Tiff file do not exists");
>
>    GDALDatasetH hDataset = GDALOpen( toStringz(fileTiff),
> GDALAccess.GA_ReadOnly );
>
>    GDALDriverH  hDriver;
>    hDriver = GDALGetDatasetDriver(hDataset);
>
>    double adfGeoTransform[6];
>
>    if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
>    {
>      writeln(adfGeoTransform[1]);
>    }
>
>
> function (void*, double*) is not callable using argument types (void*,
> double[6])
>
> I can't understand why this error is rise up. It's look like 1-to-1 with
> C code.
>
> Also I can't understand at what moment adfGeoTransform get in it value.

GDALGetGeoTransform is declared to take a pointer to a double (array of doubles). While adfGeoTransform is declared as a static array [1] of doubles. Static arrays are stack allocated and passed by value, the function expects an array which is passed by reference. Try adding ".ptr" to "adfGeoTransform" in the call to GDALGetGeoTransform.

[1] http://dlang.org/arrays.html#static-arrays

-- 
/Jacob Carlborg
April 12, 2015
Jacob, thanks!

  double [6] adfGeoTransform;

  if( GDALGetGeoTransform( hDataset, adfGeoTransform.ptr ) == 0 )
  {
    writeln(adfGeoTransform[1]);
  }

But could you explain why if binding have next string:

enum CPLErr
{
    CE_None = 0,
    CE_Debug = 1,
    CE_Warning = 2,
    CE_Failure = 3,
    CE_Fatal = 4
}

I can't use:
if( GDALGetGeoTransform( hDataset, adfGeoTransform.ptr ) == CE_None )

>Error: undefined identifier CE_None
April 12, 2015
Oh in gdal.d there is comment:

 /*
  * The enum CPLErr is defined in the header file cpl_error.h. I have not
  * for the time being included a binding to that header, but have just
  * imported this single symbol from it.
  *
  * Similarly, GDALProgressFunc is defined in port/cpl_progress.h
  */

Am I right understand that binding is not file with .d extension? So what is this file with extern(C) and so on. It's named interface file?
April 12, 2015
On 2015-04-12 11:53, Suliman wrote:

> But could you explain why if binding have next string:
>
> enum CPLErr
> {
>      CE_None = 0,
>      CE_Debug = 1,
>      CE_Warning = 2,
>      CE_Failure = 3,
>      CE_Fatal = 4
> }
>
> I can't use:
> if( GDALGetGeoTransform( hDataset, adfGeoTransform.ptr ) == CE_None )

In D you need to include the name of the enum type as well: CPLErr.CE_None. If you want to avoid that you can use aliases:

alias CE_None = CPLErr.CE_None

Or the with-statement:

with (CPLErr)
{
  // inside this block all the members of CPLErr can be accessed without prefixing them with CPLErr
  if( GDALGetGeoTransform( hDataset, adfGeoTransform.ptr ) == CE_None )
  {
  }
}

-- 
/Jacob Carlborg
April 12, 2015
On 2015-04-12 11:57, Suliman wrote:
> Oh in gdal.d there is comment:
>
>   /*
>    * The enum CPLErr is defined in the header file cpl_error.h. I have not
>    * for the time being included a binding to that header, but have just
>    * imported this single symbol from it.
>    *
>    * Similarly, GDALProgressFunc is defined in port/cpl_progress.h
>    */
>
> Am I right understand that binding is not file with .d extension? So
> what is this file with extern(C) and so on. It's named interface file?

Based on that comment it sounds like the bindings are not complete. In this case only CPLErr has been included from the cpl_progress.h file.

-- 
/Jacob Carlborg