Recent

Author Topic: DLL header import using H2PAS  (Read 2068 times)

OldBones

  • Newbie
  • Posts: 1
DLL header import using H2PAS
« on: January 20, 2018, 08:12:13 pm »
Long time since using Pascal (Delphi 6)
Now want to access CH341 USB interface chip. (Parallel, I2C and serial)
Downloaded its driver (dll and h files) and translated from Chinese.
Now trying to use H2Pas to convert h to pas. It completes without error but the resulting pas file chokes after the first 50 lines at :

typedef struct _WIN32_COMMAND {
 union {
  ULONG  mFunction;
  NTSTATUS mStatus;
 };
 ULONG mLength;
 union {
  mUSB_SETUP_PKT mSetupPkt;
  UCHAR mBuffer[ mCH341_PACKET_LENGTH ];
 };
} mWIN32_COMMAND, *mPWIN32_COMMAND;


It seems to lose sync trying to parse it and subsequent items and just inserts (lots of)

(* error
     };
 in member_list *)[/i]

error messages.
Is there anything I can do about it?
(btw NTSTATUS = LONG;)



jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: DLL header import using H2PAS
« Reply #1 on: January 21, 2018, 03:44:03 am »
its because there is no "Anonymous" Records in Fpc that I can see..

 The first union has no tag name for the  union..

 so to have a union (Variant) in the first location and still have one in the second without
tag names is a problem.

 The "CASE" inside a record acts as the union however, somewhere in pascal history the END of the
case becomes the end of the record too which I find ironic.. which also means variant records must
fall at the end.

 If you want one before that,  you need to wrap it with a RECORD however, it seems fpc does not
have a Anonymous Record so your forced to add a name to it which means you need to edit all
references made to it.


 
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: DLL header import using H2PAS
« Reply #2 on: January 21, 2018, 03:46:36 am »
Code: Pascal  [Select][+][-]
  1. Type  WIN32_Command = record
  2.      Record
  3.       Case Integer of
  4.        3:  (mFunction :LongWord);
  5.        4:  (mStatus   :Integer); //NTSTATUS ? Replaced with Integer for now.
  6.       End;
  7.    Case integer of
  8.    0: (mSetUpPkt:Integer);// mUSB_SETUP_PKT_mSetupPKt; Integer for now..
  9.    1: (mBuffer:array[0..100]{CH341_PACKET_LENGTH]} of byte);
  10.  End;                

Just an example as to what it should look like.
The only true wisdom is knowing you know nothing

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: DLL header import using H2PAS
« Reply #3 on: January 21, 2018, 04:09:23 am »
Just an example as to what it should look like.
...
...compilation error. Try this:
Code: Pascal  [Select][+][-]
  1. uses JwaWinType;
  2.  
  3. type
  4.   mPWIN32_COMMAND = ^_WIN32_COMMAND;
  5.   mWIN32_COMMAND = _WIN32_COMMAND;
  6.   _WIN32_COMMAND = record
  7.     case Byte of
  8.       0: (mFunction: ULONG;
  9.           mLength: ULONG;
  10.           case Byte of
  11.             0: (mSetUpPkt: mUSB_SETUP_PKT);
  12.             1: (mBuffer: array [0..mCH341_PACKET_LENGTH - 1] of UCHAR);
  13.           );
  14.       1: (mStatus: NTSTATUS);
  15.   end;

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: DLL header import using H2PAS
« Reply #4 on: January 21, 2018, 04:19:23 am »
what a mess...

 we need a real anonymous function with closure control within.
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: DLL header import using H2PAS
« Reply #5 on: January 21, 2018, 08:51:39 am »
I don't see what you mean. ASerge's solution is the proper one.

BTW, as I wrote before:
First run cpp -E, then h2paspp then h2pas... Not just h2pas.
Specialize a type, not a var.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: DLL header import using H2PAS
« Reply #6 on: January 21, 2018, 07:43:23 pm »
Using nested Case statements for variant fields makes the record show the data fields out of
place.

 When I look at a record  I want to see the order in which the fields are defined and make them look
just like the original Struct.

 Looking at Serge's example you can see that in the first Case statement  you have two fields that use
the same location of the main record, the first one is at the top where it should be and the next one is
way at the bottom, but in reality that isn't where it is in memory.. The one at the bottom is just an
overlay of the one at the top but yet there is other field members between, that is miss representing the
layout of the record when looking at it from the coder's perspective.

 This all can be easily corrected if the compiler would understand "Anonymous" Records within a define of a
record and the lay out would then represent the layout of the original when viewing it.

  for example..
Type Main_Record = Record
    Record   // << need the ability to do this without a RECORD Tag name.
       case byte of
         0:(FieldOne:Byte;);
         1:(FieldTwo:Word);.
       End;
  ....
End;
 if the UNION is named then it is no issue because then you can name the record and it works however,
we have cases where the UNION isn't named and now there is a problem and thus comes along Serge's example
demonstrating the complexity of the format where it now just makes it look like a foreign record compared to the
original

    I hope you understand better now.

The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018