Recent

Author Topic: How to provide a pointer as an argument instead of a function  (Read 1248 times)

PascalB

  • Newbie
  • Posts: 2
I am using an audio library called BASS for my Windows application. It is written in C, but it is available as an external library in the form of a DLL file. A Pascal unit is provided to interact with the DLL, and while it is targeted for Delphi, it works fine with FreePascal, except for one method that is causing me issues:

Code: Pascal  [Select][+][-]
  1. function BASS_WASAPI_Init(device:Integer; freq,chans,flags:DWORD; buffer,period:Single; proc:WASAPIPROC; user:Pointer): BOOL; stdcall; external basswasapidll;

The method BASS_WASAPI_Init requires me to provide a WASAPIPROC function in the proc parameter. The function is defined as such:

Code: Pascal  [Select][+][-]
  1. type
  2.   WASAPIPROC = function(buffer:Pointer; length:DWORD; user:Pointer): DWORD; stdcall;

However, BASS also allows for a "special WASAPIPROC" named WASAPIPROC_BASS. It is defined as such:

Code: Pascal  [Select][+][-]
  1. const
  2.   WASAPIPROC_BASS = Pointer(-1);

For the needs of my project, I need to use WASAPIPROC_BASS. Thus, I write:

Code: Pascal  [Select][+][-]
  1. Mixer := BASS_Mixer_StreamCreate(48000, 2, BASS_STREAM_DECODE or BASS_SAMPLE_FLOAT or BASS_MIXER_NONSTOP);
  2. BASS_WASAPI_Init(-1, 48000, 2, BASS_WASAPI_EXCLUSIVE, 0.03, 0, WASAPIPROC_BASS, Pointer(Mixer));

This works fine on Delphi, but fails on Lazarus with the following error:

Code: Pascal  [Select][+][-]
  1. Error: Incompatible type for arg no. 7: Got "Pointer", expected "<procedure variable type of function(Pointer;LongWord;Pointer):DWord;StdCall>"

A possible workaround is to use the {$mode Delphi} directive, but I wanted to know if there was any way to solve this issue with the default {$mode ObjFPC} directive.

cdbc

  • Hero Member
  • *****
  • Posts: 1673
    • http://www.cdbc.dk
Re: How to provide a pointer as an argument instead of a function
« Reply #1 on: July 13, 2024, 07:32:51 am »
Hi
How about:
Code: Pascal  [Select][+][-]
  1. // instead of regular-pointer cast the -1 to a function-pointer
  2. WASAPIPROC_MINE = WASAPIPROC(-1);
  3.  
Give it what it wants, pass the above in and see what happens...
Maybe mode '{$mode ObjFPC}' is a little stricter, than '{$mode Delphi}'?!?
...Or you could just implement the function as a null-function, i.e.: function defined as usual, but doesn't do anything and then pass that in...
edit2: Remember to pass it like '@WASAPIPROC_MINE' in mode objfpc.
Regards Benny
« Last Edit: July 13, 2024, 07:39:28 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

PascalB

  • Newbie
  • Posts: 2
Re: How to provide a pointer as an argument instead of a function
« Reply #2 on: July 13, 2024, 01:14:49 pm »
Casting the -1 as a function-pointer did the trick! Thanks.

I did:

Code: Pascal  [Select][+][-]
  1. BASS_WASAPI_Init(-1, 48000, 2, BASS_WASAPI_EXCLUSIVE, 0.03, 0, WASAPIPROC(WASAPIPROC_BASS), Pointer(Mixer));
« Last Edit: July 13, 2024, 10:28:02 pm by PascalB »

TRon

  • Hero Member
  • *****
  • Posts: 3647
Re: How to provide a pointer as an argument instead of a function
« Reply #3 on: July 13, 2024, 01:19:31 pm »
There is a unwritten preference that many (if not all) Pascal developers use ans that is to prefix all types with a (capital) T as it prevents mixing types with variables etc.

I'm always amazed at how many headers from c libs are ported that do not use that convention and leads to all kind of mixups.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

440bx

  • Hero Member
  • *****
  • Posts: 4744
Re: How to provide a pointer as an argument instead of a function
« Reply #4 on: July 13, 2024, 01:40:45 pm »
I'm always amazed at how many headers from c libs are ported that do not use that convention and leads to all kind of mixups.
Sometimes it's a tough call.  I like the translated headers to be as close to the original headers as possible which, more often than not, means not prefixing types with "T" but, I agree that leaving the prefix out in Pascal can lead to problems.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

TRon

  • Hero Member
  • *****
  • Posts: 3647
Re: How to provide a pointer as an argument instead of a function
« Reply #5 on: July 14, 2024, 07:52:24 am »
Sometimes it's a tough call.
If the original headers are well written and some thought was given to the naming of the constants, types, variables, functions and macros then it could indeed be a difficult call to make.

At least for me more often than not the only difference in those mentioned above is only the casing because somehow that makes sense in c ?

Quote
I like the translated headers to be as close to the original headers as possible which, more often than not, means not prefixing types with "T" but, I agree that leaving the prefix out in Pascal can lead to problems.
In case well written I can imagine it being a stretch but I always find myself blinking a second time when I do not see the type prefix just to make sure I understood the code. Yes, I /am/ Pascal biased :)
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

440bx

  • Hero Member
  • *****
  • Posts: 4744
Re: How to provide a pointer as an argument instead of a function
« Reply #6 on: July 14, 2024, 08:25:40 am »
I like the convention of prefixing types with "T" but I think that there are occasions when it can be problematic to use.

For instance, all Windows types as originally defined (in C of course) are not "T" prefixed, this means that when looking up documentation on the type, it's important to leave the "T" out.  Of course, in the case of Windows, it's almost automatic to strip the "T" when looking up documentation for the type.

I very recently translated the Zydis bindings from C to Pascal and faced the choice of using a "T" prefix or not.  I decided against it because I felt it would be less error prone when looking up type documentation (which is, of course, all C centric.)  That way, whoever uses those bindings can very quickly see that everything is just about as close as possible to their C counterparts.


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

TRon

  • Hero Member
  • *****
  • Posts: 3647
Re: How to provide a pointer as an argument instead of a function
« Reply #7 on: July 14, 2024, 08:37:47 am »
For instance, all Windows types as originally defined (in C of course) are not "T" prefixed, this means that when looking up documentation on the type, it's important to leave the "T" out.  Of course, in the case of Windows, it's almost automatic to strip the "T" when looking up documentation for the type.
That is indeed a valid argument that I did not consider.

In an ideal world you (w/c)ould also add Pascalified documentation for the unit but in practice I find myself skipping that step (time constraint).

Quote
I very recently translated the Zydis bindings from C to Pascal and faced the choice of using a "T" prefix or not.  I decided against it because I felt it would be less error prone when looking up type documentation (which is, of course, all C centric.)  That way, whoever uses those bindings can very quickly see that everything is just about as close as possible to their C counterparts.
Interesting library.... and at a quick glance it seems that all declarations uses the zydis or zyan prefix which makes it a lot easier to decide to omit the type prefix.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

440bx

  • Hero Member
  • *****
  • Posts: 4744
Re: How to provide a pointer as an argument instead of a function
« Reply #8 on: July 14, 2024, 08:49:00 am »
at a quick glance it seems that all declarations uses the zydis or zyan prefix which makes it a lot easier to decide to omit the type prefix.
Yes, it's very clean.  The authors did a good job.  It's fast too. :)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018