Recent

Author Topic: Conditional variable definition?  (Read 2619 times)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12025
  • FPC developer.
Re: Conditional variable definition?
« Reply #15 on: January 24, 2025, 02:58:05 pm »
Right, new attempt: Mfagnostic loops over bytes, but P16[] and p32[] in setitem access as many 16 and 32-bit elements as there are bytes, i.e. the loop iterates 2 resp 4 times too much
Correct.
What's missing is the "Step"-Size for the Iterator.
For P16 it should be 2, for P32 should be 4
Since we don't have a "Step" in For-Loop, maybe a repeat-Until with Inc(i,2) (For P16) resp. Inc(i,4) (for P32)?
And not a "normal" assignment, but maybe a System.Move?

Simply store a field that holds the real length() in units, to be set in xxx.setlength() and use that instead length(data) where appropriate.

TRon

  • Hero Member
  • *****
  • Posts: 3930
Re: Conditional variable definition?
« Reply #16 on: January 24, 2025, 04:50:00 pm »
Right, new attempt: Mfagnostic loops over bytes, but P16[] and p32[] in setitem access as many 16 and 32-bit elements as there are bytes, i.e. the loop iterates 2 resp 4 times too much
Arrgh ! :facepalm:

That is what you get when juggling too many things at the same time. No excuse though  :-[

Thank you for noticing marcov.

Another attempt then though TS should probably provide what needs to be passed along (pointer to data ?)

Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$mode objfpc}{$h+}
  4. {$modeswitch advancedrecords}
  5.  
  6. (*
  7.     procedure MyProc(aInteger: Integer; Bitness: byte);
  8.     var
  9.        myData16: array of word;
  10.       myData32: array of Dword;
  11.  
  12.  
  13.     begin
  14.       if Bitness = 16
  15.         then SetLength(myData16,xxx)
  16.         else SetLength(myData32,xxx);
  17.       //Select which var to use in each case necessary
  18.     end;
  19. *)
  20.  
  21. type
  22.   // Bitness Adaptable Dynamic Array (sort of)
  23.   TBADynArrayBitness = (bad8, bad16, bad32, bad64);
  24.   TBADynArray =
  25.   record
  26.     Data    : packed array of byte;
  27.     bitness : TBADynArrayBitness;
  28.    private
  29.     function  GetItem(Index: integer): int64;
  30.     procedure SetItem(index : integer; value: int64);
  31.     procedure Dump(const contents: boolean = true);
  32.  
  33.     procedure SetLength(Len: SizeInt);
  34.     function  GetHigh: SizeInt;
  35.     function  GetLow: SizeInt;
  36.     function  GetLength: SizeInt;
  37.    public
  38.     property  Items[index: integer]: int64 read getItem write SetItem; default;
  39.   end;
  40.  
  41.  
  42. function Low(DynArr: TBADynArray): SizeInt;
  43. begin
  44.   result := DynArr.GetLow;
  45. end;
  46.  
  47. function High(DynArr: TBADynArray): SizeInt;
  48. begin
  49.   result := DynArr.GetHigh;
  50. end;
  51.  
  52. function Length(DynArr: TBADynArray): SizeInt;
  53. begin
  54.   result :=  DynArr.GetLength;
  55. end;
  56.  
  57. procedure SetLength(var DynArr: TBADynArray; Len: SizeInt);
  58. begin
  59.   DynArr.SetLength(Len);
  60. end;
  61.  
  62.  
  63. { TBADynArray }
  64.  
  65.  
  66. function  TBADynArray.GetLength: SizeInt;
  67. begin
  68.   result := system.Length(Self.Data) shr ord(Self.Bitness);
  69. end;
  70.  
  71. procedure TBADynArray.SetLength(Len: SizeInt);
  72. begin
  73.   System.SetLength(Self.Data, Len * 1 shl ord(Self.Bitness));
  74. end;
  75.  
  76. function  TBADynArray.GetLow: SizeInt;
  77. begin
  78.   result := System.Low(Self.Data);
  79. end;
  80.  
  81. function  TBADynArray.GetHigh: SizeInt;
  82. begin
  83.   result := Self.GetLength - 1;
  84. end;
  85.  
  86. function  TBADynArray.GetItem(Index: integer): int64;
  87. var
  88.   P8  : PByte;
  89.   P16 : PWord;
  90.   P32 : PDWord;
  91.   P64 : PQWord;
  92. begin
  93.   case Self.Bitness of
  94.     bad8  : begin P8  := @Self.Data[0]; result := P8 [Index]; end;
  95.     bad16 : begin P16 := @Self.Data[0]; result := P16[Index]; end;
  96.     bad32 : begin P32 := @Self.Data[0]; result := P32[Index]; end;
  97.     bad64 : begin P64 := @Self.Data[0]; result := P64[Index]; end;
  98.   end;
  99. end;
  100.  
  101. procedure TBADynArray.SetItem(index: integer; value: int64);
  102. var
  103.   P8  : PByte;
  104.   P16 : PWord;
  105.   P32 : PDWord;
  106.   P64 : PQWord;
  107. begin
  108.   case Self.bitness of
  109.     bad8  : begin P8  := @Self.Data[0]; P8 [index] :=  byte(value); end;
  110.     bad16 : begin P16 := @Self.Data[0]; P16[index] :=  word(value); end;
  111.     bad32 : begin P32 := @Self.Data[0]; P32[index] := dword(value); end;
  112.     bad64 : begin P64 := @Self.Data[0]; P64[index] := qword(value); end;
  113.   end;
  114. end;
  115.  
  116. procedure TBADynArray.Dump(const contents: boolean = true);
  117. var
  118.   i: integer;
  119. begin
  120.   writeln('bitness         = ', Self.Bitness);
  121.   writeln('#bytes in array = ', System.Length(Self.Data));
  122.   writeln('#items in array = ', Self.GetLength);
  123.   writeln('address of data = $', HexStr(@Self.Data[0]));
  124.  
  125.   if contents then
  126.     for i := System.Low(Self.Data) to System.High(Self.Data)
  127.       do writeln(Self.Data[i]:3);
  128. end;
  129.  
  130. ///////////////////////////////////////////////////////////////////////////////
  131.  
  132. procedure Mfagnostic(var inData: TBADynArray);
  133. var
  134.   i: integer;
  135. begin
  136.   for i := low(inData) to High(inData)
  137.     do InData[i]:= i;
  138.  
  139.   writeln;
  140.   inData.Dump;
  141.   writeln;
  142.  
  143.   for i := low(inData) to High(inData)
  144.     do writeln(InData[i]);
  145. end;
  146.  
  147. procedure example;
  148. var
  149.   MyData : TBADynArray;
  150. begin
  151.   MyData := default(TBADynArray);
  152.   MyData.Bitness := bad64;
  153.   SetLength(MyData, 10);
  154.   mfagnostic(MyData);
  155. end;
  156.  
  157. procedure multitest;
  158. var
  159.   MyData  : TBADynArray;
  160.   bitness : TBADynArrayBitness;
  161. begin
  162.   MyData := default(TBADynArray);
  163.   for bitness in TBADynArrayBitness do
  164.   begin
  165.     MyData.Bitness := bitness;
  166.     SetLength(MyData, 2);
  167.     MyData.Dump(false);
  168.   end;
  169. end;
  170.  
  171. begin
  172.   multitest;
  173.   writeln;
  174.   example
  175. end.
  176.  

I solved the stepping in a slightly other manner (might be for the better might be for the worse).
I do not have to remember anything anymore thanks to total-recall.

CM630

  • Hero Member
  • *****
  • Posts: 1247
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Conditional variable definition?
« Reply #17 on: January 29, 2025, 11:36:52 am »

...
Another attempt then though TS should probably provide what needs to be passed along (pointer to data ?)
...
I do not know what TS means, but if it happens to be me, here is my current code:



Code: Pascal  [Select][+][-]
  1.  
  2. function TfrmMain.TakeWaveMCC(BoardNum: byte; LowChan: byte; HighChan: byte; const SamplesPerChannel: Integer; RefreshRate: integer; Bitness: byte):tWDArray;
  3. var
  4.    //MCC DAQ vars
  5.    ULStat:           Integer;
  6.    MemHandle:        Integer;
  7.    ADDataW:          array of Word;
  8.    ADDataDW:         array of DWord;
  9.    Revlevel:         Single;
  10.    Count :           Integer = 0;
  11.    Range :           Integer = 0;
  12.    //MCC DAQ vars END
  13.  
  14.  
  15.   DataIndex:         integer = 0;
  16.   ChanIndex:         integer = 0;
  17.   SampleIndex:       integer = 0;
  18.   ChannelCount:      integer;
  19.   EngUnits:          Double;
  20. begin
  21.   SetLength(Result.Data,0);
  22.   RevLevel:=CURRENTREVNUM; //Declare Revision Level, does not seem to have any practical usage
  23.   ULStat:=cbDeclareRevision(RevLevel);
  24.   ULStat:=cbErrHandling(PRINTALL,STOPALL); {set Universal Library to print all errors;set Universal Library to stop on errors}
  25.  
  26.  
  27.   ChannelCount:= HighChan - LowChan + 1;
  28.   Count:= SamplesPerChannel * ChannelCount;
  29.   {set up a buffer in Windows to contain the data}
  30.   MemHandle:=cbWinBufAlloc (Count,16);
  31.   if Bitness = 16
  32.     then SetLength(ADDataW,Count)
  33.     else SetLength(ADDataDW,Count);
  34.   ULStat:=cbAInScan(BoardNum,LowChan,HighChan,Count,RefreshRate,Range,MemHandle,0);
  35.   If ULStat <> 0 then exit;
  36.   if Bitness = 16
  37.    then ULStat:=cbWinBufToArray (MemHandle,ADDataW[0],0,Count)
  38.    else ULStat:=cbWinBufToArray (MemHandle,ADDataDW[0],0,Count);
  39.  
  40.  
  41.   If ULStat <> 0 then exit;
  42.  
  43.  
  44.   SetLength(Result.Data,ChannelCount);
  45.   for ChanIndex:= 0 to (ChannelCount -1) do
  46.     SetLength(Result.Data[ChanIndex].Values,SamplesPerChannel);
  47.   SampleIndex :=0;
  48.   DataIndex :=0;
  49.   repeat
  50.     for ChanIndex := 0 to (ChannelCount - 1) do
  51.     begin
  52.       if Bitness = 16
  53.         then ULStat:=cbToEngUnits(BoardNum,Range,ADDataW[DataIndex],EngUnits)
  54.         else ULStat:=cbToEngUnits(BoardNum,Range,ADDataDW[DataIndex],EngUnits);
  55.       Result.Data[ChanIndex].Values[SampleIndex] := EngUnits;
  56.       inc (DataIndex);
  57.     end;
  58.     inc(SampleIndex);
  59.   until (DataIndex > (Count -1));
  60.  
  61.  
  62.   for ChanIndex := 0 to (ChannelCount - 1) do
  63.   begin
  64.     Result.Data[ChanIndex].Count:=SamplesPerChannel;
  65.     Result.Data[ChanIndex].dt:=1/RefreshRate;
  66.     Result.Data[ChanIndex].Date:=Now;
  67.     Result.Data[ChanIndex].Time:=Now;
  68.   end;
  69.   ULStat:=cbWinBufFree (MemHandle);
  70. end;
  71.  

For example, here is one of the functions, which can be called with different params:

Code: Pascal  [Select][+][-]
  1. ...
  2.  
  3. function cbToEngUnits (BoardNum:Integer; Range:Integer; DataVal: Word; var EngUnits:Double):Integer;
  4. var
  5.   mEngUnit: single;
  6. begin
  7.   Result := cbToEngUnits16(BoardNum,Range,DataVal,single(mEngUnit));
  8.   EngUnits := Double(mEngUnit);
  9. end;
  10.  
  11.  
  12. function cbToEngUnits (BoardNum:Integer; Range:Integer; DataVal:DWord; var EngUnits:Double):Integer; overload;
  13. begin
  14.   Result := cbToEngUnits32(BoardNum,Range,DataVal,EngUnits);
  15. end;
  16. ...
  17.   TcbToEngUnits16          =function  (BoardNum:Integer; Range:Integer; DataVal:Word;  var EngUnits:Single):Integer; StdCall;
  18.  
  19.   TcbToEngUnits32          =function  (BoardNum:Integer; Range:Integer; DataVal:DWord; var EngUnits:Double):Integer; StdCall;
  20. ...
  21.  
  22.  
  23.  
  24.       cbToEngUnits16:=          TcbToEngUnits16(GetProcedureAddress            (DLLHandle, 'cbToEngUnits'));
  25.       cbToEngUnits32:=          TcbToEngUnits32(GetProcedureAddress            (DLLHandle, 'cbToEngUnits32'));
  26.  



Looking at your code, the cure seems worse than the disease, so keeping my current code seems fine.
« Last Edit: January 29, 2025, 11:38:57 am by CM630 »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

alpine

  • Hero Member
  • *****
  • Posts: 1343
Re: Conditional variable definition?
« Reply #18 on: January 29, 2025, 01:40:42 pm »
Quote
So the question is it possible to use only one variable and define according to my needs. I think in C I can define a variable wherever I want (there is no dedicated var section there).
So I am trying to find if the same is doable in FPC:
  if a = true then MyData : array of Word else MyData : array of DWord;
It doesn't work that way, even in C, you can write like:
Code: C  [Select][+][-]
  1. if(c)
  2. {
  3.   uint16_t mydata[n];
  4. }
  5. else
  6. {
  7.   uint32_t mydata[n];
  8. }
but the arrays will be valid only into their enclosing brackets. You can do the same in FPC by declaring each in a separate nested procedure:
Code: Pascal  [Select][+][-]
  1. procedure A;
  2.  
  3.   procedure x16;
  4.   var MyData : array of Word;
  5.   begin
  6.   end;
  7.  
  8.   procedure x32;
  9.   var MyData : array of DWord;
  10.   begin
  11.   end;
  12.  
  13. begin
  14.   if a then x16 else x32;
  15. end;
Actually it won't solve your problem, though.

IMO the simplest thing you can do was already given by TRon in reply #5. Assigning P16, P32 to the beginning of the Data allows using the same memory simultaneously as Word (through P16[ x ]) and DWord (through P32[ x ]) array.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

TRon

  • Hero Member
  • *****
  • Posts: 3930
Re: Conditional variable definition?
« Reply #19 on: January 30, 2025, 06:58:13 am »
I do not know what TS means, but if it happens to be me, here is my current code:
TS stands for Topic Starter aka OP (Original Poster) so yes I tried to address you :)

Reason to do so is to make sure that you are able to access the data as required.

BTW: I understand that you are depending on a 3th party library but oh dear what a screw up in providing such an API.

Quote
Looking at your code, the cure seems worse than the disease, so keeping my current code seems fine.
It is just one way of abstracting and I had to account (at least I tried) for every possible scenario.

I don't believe there is a non scriptable language that offers what you seem to be looking for though (but feel free to correct). If there exists even something like that then it would also be behind some fancy abstraction.

Perhaps someone else is able to come up with something more practicable but it would not be something that you'd expect.

But, if you are prefer your original code over more elaborated code such as presented then there is nothing wrong with that  :)
I do not have to remember anything anymore thanks to total-recall.

CM630

  • Hero Member
  • *****
  • Posts: 1247
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Conditional variable definition?
« Reply #20 on: January 30, 2025, 08:04:33 am »

It doesn't work that way, even in C, you can write like:
Code: C  [Select][+][-]
  1. if(c)
  2. {
  3.   uint16_t mydata[n];
  4. }
  5. else
  6. {
  7.   uint32_t mydata[n];
  8. }
but the arrays will be valid only into their enclosing brackets.
Code: C  [Select][+][-]
  1. if(c){  uint16_t mydata[n];}else{  uint32_t mydata[n];}
  2. Serial.write("Value i = %d",mydata[n]) ;
  3.  
  4.  

So if I get you right, Serial.printf("Value i = %d",mydata[n]); will not work, because it is out of the brackets of the if statement (I C only in Arduino)?

BTW: I understand that you are depending on a 3th party library but oh dear what a screw up in providing such an API.
Err, the thread is in the Beginners sections after all. The previous time I addressed a DLL was in 2014, it was actually an older version of the same one.
And I have not made any progress with programming since then.

« Last Edit: January 30, 2025, 08:08:44 am by CM630 »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

TRon

  • Hero Member
  • *****
  • Posts: 3930
Re: Conditional variable definition?
« Reply #21 on: January 30, 2025, 08:17:02 am »
BTW: I understand that you are depending on a 3th party library but oh dear what a screw up in providing such an API.
Err, the thread is in the Beginners sections after all. The previous time I addressed a DLL was in 2014, it was actually an older version of the same one.
And I have not made any progress with programming since then.
Uhm, I think there is a misunderstanding unless you are the author of that library ?

As a developer we have to deal with whatever the 3th party comes up with in order use their API. It is their API that sucks (in particular using 2 separate functions in order to basically do the same thing, e.g. only passing another sized type) :)
I do not have to remember anything anymore thanks to total-recall.

CM630

  • Hero Member
  • *****
  • Posts: 1247
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Conditional variable definition?
« Reply #22 on: January 30, 2025, 08:44:59 am »
This is a Measurement Computing library (I think you mentioned, that you have some experience with them).
It seems that initially, they made 16-bit DAQs only, but it occurs, that now they make daqs with more than 16 bits (in my case it is a 18-bit daq).
So yes, they same two separate functions, to do the same thing- ones for 16-bit DAQs and others for >16 bit DAQs (they have the same name, but with the “32” suffices).
(https://sourceforge.net/p/lazmer/code/HEAD/tree/trunk/daqlibs/MCCULDynBind.pas)

Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

440bx

  • Hero Member
  • *****
  • Posts: 4987
Re: Conditional variable definition?
« Reply #23 on: January 30, 2025, 08:46:31 am »
I'm going to suggest a method of handling the different array types at runtime.

Step 1. Basically, take a page off the OOP book.  That is, create a table of function/procedure pointers (conceptually similar to the object/class VMT.) 

Step 2. Create two sets of functions/procedures, one set for the 16 bit array, the other for the 32 bit array.

immediately after the dll has told the calling program the type of array it needs, populate the table with pointers to the _appropriate_ functions created in Step 2.

That way, testing for 16 or 32 bit is done only once to populate the table of functions with the functions that operate on the type the dll has requested.  Once that is done, the rest of the program uses those function without even having to know what bitness it is dealing with because all the bitness dependent stuff is localized in those functions.

The "problem" might be that to set that up, the programmer has to be reasonably comfortable with pointers and function pointers in particular.  If not comfortable with pointers, forget all of the above.

HTH.

While re-reading this stuff, it occurred to me that it might be possible to create a class that uses pointers to "procedure of object", that way the class would become the table of pointers I mentioned in Step 1.

Since, I never use objects/classes this is not something I can help with but, someone who is well versed probably gets what I'm getting at and knows how to implement it using classes.  Personally, I just suspect it can be done that way but, have no idea how.

HTH2.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

alpine

  • Hero Member
  • *****
  • Posts: 1343
Re: Conditional variable definition?
« Reply #24 on: January 30, 2025, 10:59:22 am »
So if I get you right, Serial.printf("Value i = %d",mydata[n]); will not work, because it is out of the brackets of the if statement (I C only in Arduino)?
Exactly. That is because they're declared in the local scope of their {...} block. You can omit the curly braces but then the whole block will be just the declaration, which is actually useless.

BTW the Arduino script is a full blown gcc with a predefined main() and just links against your (so called) script.

I don't see any problem with your current sources, IMHO no need to use fancy features for the sake of just using them. You can follow the advice from TRon given earlier: allocate an array which is big enough and then access it with P16[ i ] or P32[ i ] according to the bitness.

One more thing - the overloading of cbToEngUnits. The difference is only in one parameter (DataVal:D/Word) which is ambiguous. According to the data widening rules the compiler may decide to invoke the wrong variant.  Generally speaking, this is not a good practice because every time you see a call, you have to remember all the options and take into account the type of the actual parameters.   

Edit:
In your source:
Code: Pascal  [Select][+][-]
  1. MemHandle:=cbWinBufAlloc (Count,16);
Shouldn't it be:
Code: Pascal  [Select][+][-]
  1. MemHandle:=cbWinBufAlloc (Count, Bitness);
?
« Last Edit: January 30, 2025, 11:33:18 am by alpine »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

CM630

  • Hero Member
  • *****
  • Posts: 1247
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Conditional variable definition?
« Reply #25 on: January 30, 2025, 04:16:41 pm »
...
Edit:
In your source:
Code: Pascal  [Select][+][-]
  1. MemHandle:=cbWinBufAlloc (Count,16);
Shouldn't it be:
Code: Pascal  [Select][+][-]
  1. MemHandle:=cbWinBufAlloc (Count, Bitness);
?

Code: Pascal  [Select][+][-]
  1. { Bitness }
  2.   bit8  =  8;
  3.   bit16 = 16;
  4.   bit32 = 32;
  5.   bit64 = 64;
If no legacy interfered it should be Bitness, indeed. But considering legacy... hard to say.

I hope I will find sufficient time and wit for the other explanations and advice...
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

alpine

  • Hero Member
  • *****
  • Posts: 1343
Re: Conditional variable definition?
« Reply #26 on: January 30, 2025, 05:33:52 pm »
You wrote the ЛазМер bindings, you should know better, but I'm pretty sure you'll overrun the buffer the very first time bitness happened to be > 16.

Digging into your code and into DLL docs:

Code: Pascal  [Select][+][-]
  1. function cbWinBufAlloc(NumPoints:Longint; aBitness: byte):Integer;
  2. begin
  3.   case aBitness of
  4.     bit32 : Result := cbWinBufAlloc32(NumPoints);
  5.     bit64: Result := cbWinBufAlloc64(NumPoints);
  6.     else Result := cbWinBufAlloc16 (NumPoints);
  7.   end; //case
  8. end;
  9.  
From the https://files.digilent.com/manuals/Mcculw_WebHelp/Function_Reference/Windows_Memory_Management_Functions/cbWinBufAlloc32.htm :
Quote
Arguments
NumPoints
  The size of the buffer to allocate. Specifies how many data points (32-bit integers, NOT bytes) can be stored in the buffer.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

CM630

  • Hero Member
  • *****
  • Posts: 1247
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Conditional variable definition?
« Reply #27 on: January 31, 2025, 08:21:23 am »

I decided to change
function cbWinBufAlloc(NumPoints:Longint; aBitness: byte):Integer;
[/size]to
[/size]function cbWinBufAlloc(NumPoints:Longint; Resolution: byte):Integer;
[/size]because the resolution is the parameter provided by the manufacturer, it might be anything up to xxx bit, currently maybe not more than 24. An I will switch internally.

[/size]I do not understand what bothers you in the mentioned function.
[/size]If NumPoints = 100, then cbWinBufAlloc16 will allocate 200 bytes (16 bits per point); cbWinBufAlloc32 will allocate 400 bytes.
[/size]Deeming on your comment, I suppose that one can use cbWinBufAlloc16(int(NumPoints*2)); instead of cbWinBufAlloc32;
[/size]In fact this is what happens - if I use cbWinBufAlloc32 for a ≤16 bit device - in the array that I get from the DLL the first half contains all the data, the second half contains nothing.
« Last Edit: January 31, 2025, 09:16:52 am by CM630 »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

alpine

  • Hero Member
  • *****
  • Posts: 1343
Re: Conditional variable definition?
« Reply #28 on: January 31, 2025, 11:45:55 am »
What bothers me is that in your code:
Code: Pascal  [Select][+][-]
  1.   ...
  2.   {set up a buffer in Windows to contain the data}
  3.   MemHandle:=cbWinBufAlloc (Count,16);
  4.   if Bitness = 16
  5.     then SetLength(ADDataW,Count)
  6.     else SetLength(ADDataDW,Count);
  7.   ULStat:=cbAInScan(BoardNum,LowChan,HighChan,Count,RefreshRate,Range,MemHandle,0);
  8.   If ULStat <> 0 then exit;
  9.   ...
On line #3 you'll allocate (Count*2) bytes total. Assuming the bitness is 32 the cbAInScan in line #7 will try to collect Count samples each of 32 bits, total of (Count*4) bytes. It will overrun the buffer.

Excerpt from cbAInScan docs:
Quote
MemHandle

Handle for the Windows buffer to store data. This buffer must have been previously allocated. For 16-bit data, create the buffer with cbWinBufAlloc(). For data that is >16-bit and ≤32-bit, use cbWinBufAlloc32(). For data that is >32-bit and ≤64-bit, use cbWinBufAlloc64(). When using scaled data, use cbScaledWinBufAlloc().
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

CM630

  • Hero Member
  • *****
  • Posts: 1247
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Conditional variable definition?
« Reply #29 on: January 31, 2025, 10:15:32 pm »
Opps, up..., indeed it should be MemHandle:=cbWinBufAlloc (Count,Bitness);

Edit: I have just reached a nice number of posts.
« Last Edit: January 31, 2025, 10:25:04 pm by CM630 »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

 

TinyPortal © 2005-2018