www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - call Pascal DLL functions from D

reply Oleg B <code.viator gmail.com> writes:
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;

     ...
}
```


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
Oct 24 2017
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Oct 24 2017
parent Oleg B <code.viator gmail.com> writes:
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.
Oct 25 2017
prev sibling next sibling parent reply Basile B. <b2.temp bb.temp.ll> writes:
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;

     ...
 }
 ```


 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.
Oct 24 2017
parent reply Oleg B <code.viator gmail.com> writes:
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).
Oct 25 2017
parent Basile B. <b2.temp 1234.b2.io.ioagain> writes:
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.
Oct 25 2017
prev sibling parent Andre Pany <andre s-e-a-p.de> writes:
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é
Oct 24 2017