4

I have this C code:

/*
  WARNING:  The order of this table must also match the order of a table
  located in AcquireResizeFilter() in "resize.c" otherwise the users filter
  will not match the actual filter that is setup.
*/
typedef enum
{
  UndefinedFilter,
  PointFilter,
  BoxFilter,
  TriangleFilter,
  HermiteFilter,
  HannFilter,
  HammingFilter,
  BlackmanFilter,
  GaussianFilter,
  QuadraticFilter,
  CubicFilter,
  CatromFilter,
  MitchellFilter,
  JincFilter,
  SincFilter,
  SincFastFilter,
  KaiserFilter,
  WelchFilter,
  ParzenFilter,
  BohmanFilter,
  BartlettFilter,
  LagrangeFilter,
  LanczosFilter,
  LanczosSharpFilter,
  Lanczos2Filter,
  Lanczos2SharpFilter,
  RobidouxFilter,
  RobidouxSharpFilter,
  CosineFilter,
  SplineFilter,
  LanczosRadiusFilter,
  CubicSplineFilter,
  SentinelFilter  /* a count of all the filters, not a real filter */
} FilterType;

and

WandExport MagickBooleanType MagickResizeImage(MagickWand *wand,
  const size_t columns,const size_t rows,const FilterType filter)

I convert it to Pascal like this:

type
  FilterType =(
    UndefinedFilter,
    PointFilter,
    BoxFilter,
    TriangleFilter,
    HermiteFilter,
    HannFilter,
    HammingFilter,
    BlackmanFilter,
    GaussianFilter,
    QuadraticFilter,
    CubicFilter,
    CatromFilter,
    MitchellFilter,
    JincFilter,
    SincFilter,
    SincFastFilter,
    KaiserFilter,
    WelchFilter,
    ParzenFilter,
    BohmanFilter,
    BartlettFilter,
    LagrangeFilter,
    LanczosFilter,
    LanczosSharpFilter,
    Lanczos2Filter,
    Lanczos2SharpFilter,
    RobidouxFilter,
    RobidouxSharpFilter,
    CosineFilter,
    SplineFilter,
    LanczosRadiusFilter,
    CubicSplineFilter,
    SentinelFilter);  // a count of all the filters, not a real filter

and

function MagickResizeImage(wand: PMagickWand; const columns: size_t; rows: size_t; const filter: FilterType): MagickBooleanType; cdecl; external MagickWandDLL;

When I call MagickResizeImage(), I get an Access Violation :(

if I change const filter: FilterType to const filter: integer, it works.

Any idea what I am doing wrong?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
zeus
  • 12,173
  • 9
  • 63
  • 184

1 Answers1

10

In C on Windows an enum is an int, so 4 bytes in size. In Delphi, by default, it is a single byte, or two bytes if there are more than 256 values, and so on.

You need to ensure that your Delphi type is the same size as the C type. For instance using the MINENUMSIZE directive.

{$MINENUMSIZE 4}

Place this before you define the enumerated type.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Actually, in C, the size of an enum is implementation defined (e.g. https://stackoverflow.com/a/366026/95954). But most Visual-C++-compatible C and C++ compilers on Windows will indeed use a 32 bit value for enums, so the Delphi code should do that too. – Rudy Velthuis Feb 23 '18 at 18:19
  • @rudy I should have said C on Windows. On Windows C compilers are obliged to use 4 byte enums to adhere to the ABI. – David Heffernan Feb 23 '18 at 18:23
  • yes it's this, adding {$MINENUMSIZE 4} make everything working :) – zeus Feb 23 '18 at 18:24
  • Btw CONST in Borland-likes is generally different from C const, but afaik FPC adheres to more C like CONSTness in cdecl procedures. – Marco van de Voort Feb 23 '18 at 21:20
  • @Marco: totally unreleated to the question or answer, but doesn't FPC do what it actually should do, with const? In what way is it different for cdecl? – Rudy Velthuis Feb 23 '18 at 21:48
  • @rudy const in Pascal means that the parameter can't be modified. Delphi and FPC both do that of course. I think that both you and Marco are perhaps getting side tracked by implementation detail optimisations. – David Heffernan Feb 23 '18 at 22:03
  • @David: sidetracked indeed, but I really wonder what const would do differently in cdecl, as Marco claims. – Rudy Velthuis Feb 23 '18 at 22:06
  • I can remember there was some difference in constness between Pascal and C, and it being fixed in some FPC version. Initially, I thought it was always by reference, but it seems not to be so. Now I thought some more about it, IIRC it was something PPC or OS X related, so it is probably to remote to be relevant. Maybe the switchpoint where const changes to reference in AIX abi? – Marco van de Voort Feb 23 '18 at 23:15
  • Const and reference are not mutually exclusive. And, at least in Delphi, many const items are passed by reference anyway, even in stdcall or cdecl. But that is totally off-topic. – Rudy Velthuis Feb 23 '18 at 23:42