Thread overview
call Pascal DLL functions from D
Oct 25, 2017
Oleg B
Oct 25, 2017
Adam D. Ruppe
Oct 25, 2017
Oleg B
Oct 25, 2017
Basile B.
Oct 25, 2017
Oleg B
Oct 25, 2017
Basile B.
Oct 25, 2017
Andre Pany
October 25, 2017
Hello. I have DLL written on Pascal and "headers" for use it (types and functions signatures definitions). How I can port "headers" to D?

Calling convention is `stdcall` (`extern (Windows)` for D), arguments of some functions is structs of structs and etc with static array fields:

```Pascal
type
  TOneHarmonic = record
    Koef: Single;
    Angle: Single;
  end;

  THarmonicsArray = array[2..50] of TOneHarmonic;
  TInterharmonicsArray = array[1..49] of TOneHarmonic;

  TVoltageCurrentOneFaza = record
    KalibKoef: Single;
    IncludeMainFreq: Boolean;
    MainFreqVoltCur: TOneHarmonic;
    Harmonics: THarmonicsArray;
    Interharmonics: TInterharmonicsArray;
  end;

  TVoltageCurrent = record
    Enable: Boolean;
    NominalID: Byte;
    Faza_A: TVoltageCurrentOneFaza;
    Faza_B: TVoltageCurrentOneFaza;
    Faza_C: TVoltageCurrentOneFaza;
  end;

  TSignal = record
    HasInterharmonics: Boolean;
    Voltage: TVoltageCurrent;
    Current: TVoltageCurrent;
    ...
  end;
  ...
```

in other file

```Pascal
function CheckSignalData(SignalData: PUserSignalData): Word;
  stdcall; external SIGNALK2MDLL;
```
PUserSignalData is pointer to TUserSignalData, first field of TUserSignalData is Signal, other fields is pointers to other types

If I understand correctly
1. `Single` is `float` in D, `Byte` is `byte`, `Boolean` is `bool`, `Word` is `ushort`
2. `array[A..B] of TFoo` is `TFoo[B-A+1]` (static array)

Can I rewrite records to structs like this?

```d
alias Word = short;
alias Single = float;
alias Byte = byte;
alias Boolean = bool;

struct OneHarmonic
{
    Single coef;
    Single angle;
}

alias HarmonicArray = OneHarmonic[49];

// TVoltageCurrentOneFaza
struct PhaseInfo
{
    // Must I align fields and/or structs?
    Single calibCoef;
    Boolean includeMainFreq;
    OneHarmonic mainFreqVoltCur;
    HarmonicArray harmonics; // Can I replace Pascal static arrays with D static arrays?
    HarmonicArray interharmonics;
}

// TVoltageCurrent
struct ChannelInfo
{
    Boolean enable;
    Byte nominalID;
    PhaseInfo[3] phase; // Can I replace 3 fields to static array?
}

struct Signal
{
    Boolean hasInterharmonics;
    ChannelInfo voltage;
    ChannelInfo current; // #1
    ...
}
```

In this case I have error about current values (#1) and I think I badly rewrite Pascal records to D structs (ChannelInfo, PhaseInfo, OneHarmonic) and lose alignments and/or something else.

PS original pascal naming is very bad, I know
October 25, 2017
On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote:
> Calling convention is `stdcall` (`extern (Windows)` for D), arguments of some functions is structs of structs and etc with static array fields:

Fun fact, D has extern(Pascal): https://dlang.org/spec/attribute.html#linkage


I don't know the details  of the rest... but I think you're right about what you have so far.

I'd suggest just trying it and seeing if the functions return what you expect.
October 25, 2017
On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote:
> Hello. I have DLL written on Pascal and "headers" for use it (types and functions signatures definitions). How I can port "headers" to D?
>
> Calling convention is `stdcall` (`extern (Windows)` for D), arguments of some functions is structs of structs and etc with static array fields:
>
> ```Pascal
> type
>   TOneHarmonic = record
>     Koef: Single;
>     Angle: Single;
>   end;
>
>   THarmonicsArray = array[2..50] of TOneHarmonic;
>   TInterharmonicsArray = array[1..49] of TOneHarmonic;
>
>   TVoltageCurrentOneFaza = record
>     KalibKoef: Single;
>     IncludeMainFreq: Boolean;
>     MainFreqVoltCur: TOneHarmonic;
>     Harmonics: THarmonicsArray;
>     Interharmonics: TInterharmonicsArray;
>   end;
>
>   TVoltageCurrent = record
>     Enable: Boolean;
>     NominalID: Byte;
>     Faza_A: TVoltageCurrentOneFaza;
>     Faza_B: TVoltageCurrentOneFaza;
>     Faza_C: TVoltageCurrentOneFaza;
>   end;
>
>   TSignal = record
>     HasInterharmonics: Boolean;
>     Voltage: TVoltageCurrent;
>     Current: TVoltageCurrent;
>     ...
>   end;
>   ...
> ```
>
> in other file
>
> ```Pascal
> function CheckSignalData(SignalData: PUserSignalData): Word;
>   stdcall; external SIGNALK2MDLL;
> ```
> PUserSignalData is pointer to TUserSignalData, first field of TUserSignalData is Signal, other fields is pointers to other types
>
> If I understand correctly
> 1. `Single` is `float` in D, `Byte` is `byte`, `Boolean` is `bool`, `Word` is `ushort`

No Pascal's "Byte" is D's "ubyte". But unless NominalID goes over 127 this is not the source of the problem.

> 2. `array[A..B] of TFoo` is `TFoo[B-A+1]` (static array)

No A-B. In Pascal the upper bound of a range (like here but i'm not sure this i called like that in the grammar) or of a slice is inclusive.

>
> Can I rewrite records to structs like this?
>
> ```d
> alias Word = short;
> alias Single = float;
> alias Byte = byte;
> alias Boolean = bool;
>
> struct OneHarmonic
> {
>     Single coef;
>     Single angle;
> }
>
> alias HarmonicArray = OneHarmonic[49];

48 !

> // TVoltageCurrentOneFaza
> struct PhaseInfo
> {
>     // Must I align fields and/or structs?

No, unless the record is packed.

>     Single calibCoef;
>     Boolean includeMainFreq;
>     OneHarmonic mainFreqVoltCur;
>     HarmonicArray harmonics; // Can I replace Pascal static arrays with D static arrays?
>     HarmonicArray interharmonics;
> }
>
> // TVoltageCurrent
> struct ChannelInfo
> {
>     Boolean enable;
>     Byte nominalID;
>     PhaseInfo[3] phase; // Can I replace 3 fields to static array?

yes

> }
>
> struct Signal
> {
>     Boolean hasInterharmonics;
>     ChannelInfo voltage;
>     ChannelInfo current; // #1
>     ...
> }
> ```
>
> In this case I have error about current values (#1) and I think I badly rewrite Pascal records to D structs (ChannelInfo, PhaseInfo, OneHarmonic) and lose alignments and/or something else.
>
> PS original pascal naming is very bad, I know

Most likely the problem is the array length.
October 25, 2017
On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote:
> Hello. I have DLL written on Pascal and "headers" for use it (types and functions signatures definitions). How I can port "headers" to D?
>
> [...]

Hi,

this thread might be interesting for you, if you use Delphi
http://forum.dlang.org/post/hpodoabutuakfxbzzcyy@forum.dlang.org

This thread describes a bridge between the D Programming Language and Delphi.

Kind regards
André
October 25, 2017
On Wednesday, 25 October 2017 at 04:30:12 UTC, Basile B. wrote:
> On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote:
>> 2. `array[A..B] of TFoo` is `TFoo[B-A+1]` (static array)
>
> No A-B. In Pascal the upper bound of a range (like here but i'm not sure this i called like that in the grammar) or of a slice is inclusive.
>
>> alias HarmonicArray = OneHarmonic[49];
>
> 48 !
>
> Most likely the problem is the array length.

If I wrote `array[5..7] of ...` I get array that can be indexed by `5`, `6` and `7`, right? It means that array have 3 elements. If A=5, B=7 then length of array is B-A+1, 7-5+1=3. In my case I have [1..49] and [2..50] ranges: 49-1+1=49, 50-2+1=49. I don't understand why length must be 48...
In any case I tried 48 and CheckSignalData function returns other error code, but it point to current field too (incorrect value of coefs - it can be if floating point value is badly read).
October 25, 2017
On Wednesday, 25 October 2017 at 03:36:54 UTC, Adam D. Ruppe wrote:
> I'd suggest just trying it and seeing if the functions return what you expect.

Unfortunately they returns unexpected codes. Otherwise I wouldn't post question here. I go here then I have no idea to resolve problem.
October 25, 2017
On Wednesday, 25 October 2017 at 10:47:56 UTC, Oleg B wrote:
> On Wednesday, 25 October 2017 at 04:30:12 UTC, Basile B. wrote:
> If I wrote `array[5..7] of ...` I get array that can be indexed by `5`, `6` and `7`, right? It means that array have 3 elements. If A=5, B=7 then length of array is B-A+1, 7-5+1=3. In my case I have [1..49] and [2..50] ranges: 49-1+1=49, 50-2+1=49. I don't understand why length must be 48...

Yeah of course, me neither.