Lazarus

Free Pascal => General => Topic started by: Zvoni on October 18, 2020, 10:46:01 am

Title: Casting an Array Of Pointers to PPointer for external C-Function
Post by: Zvoni on October 18, 2020, 10:46:01 am
Hi Folks,
quick question to the experts:
I'm currently translating some C-Code, and i've come across something that has me stumped:
The C-Code itself uses some C-Libraries, for which i have the C-Bindings.
The Prototype for that external function looks like this:
Code: C  [Select][+][-]
  1. Function MyFunc(AArg1:cint;AArg2:PPointer;AArg3:PChar, SomeMoreArgs):cint;cdecl;external blablalablabla
  2.  

The C-Code which calls that function looks like this:
Code: C  [Select][+][-]
  1. uint8_t *MyVar[4]
  2. MyFunc(SomeInteger,(void **)MyVar,PChar(AString),blablabla);
  3.  
I'm aware that MyVar is an
Code: Pascal  [Select][+][-]
  1. MyVar : Array[0..3] Of PByte;
  2.  
But how do i cast it to PPointer?
The Elements of the Array are already Pointers, and i'm under the impression that the Array-Variable itself is (usually?) a Pointer to the first element, so i'm kind of stumped how to proceed.
..... PPointer(MyVar) doesn't compile
.....PPointer(@MyVar) compiles, but is it correct?
I'd like to avoid creating a hard to find bug.....

Next: I have the same cast as above but against a
Code: C  [Select][+][-]
  1. Uint32_t *MyVar2;
  2.  
So, not an Array, just a simple Pointer.
And i have to cast that to a ....(void **)AnArg .... in another C-Function with a similiar Prototype expecting a PPointer for that Argument
PPointer(MyVar2)? or PPointer(@MyVar2)?
Title: Re: Casting an Array Of Pointers to PPointer for external C-Function
Post by: BlueIcaro on October 18, 2020, 12:06:18 pm
Hello, I 'm not a expert, but you should use Ctypes in your uses clause. So you can use C types.
Code: [Select]
uses ....,ctypes;
(...)
MyVarInC := UInt32;
Other := PUInt16;
Here you can found more info:
 https://wiki.lazarus.freepascal.org/Creating_bindings_for_C_libraries  (https://wiki.lazarus.freepascal.org/Creating_bindings_for_C_libraries)
https://wiki.lazarus.freepascal.org/Pascal_for_C_users (https://wiki.lazarus.freepascal.org/Pascal_for_C_users)

/BlueIcaro
Title: Re: Casting an Array Of Pointers to PPointer for external C-Function
Post by: PascalDragon on October 18, 2020, 12:15:04 pm
In C an array variable is essentially a Pointer to the 0th element, so the correct way to translate this for you is:

Code: Pascal  [Select][+][-]
  1. MyFunc(SomeInteger, @MyVar[0],);

Similar if you only have a single element to pass you use:

Code: Pascal  [Select][+][-]
  1. MyFunc(SomeInteger, @MyVar2,);

Maybe you then also need to add a cast to PPointer.

Hello, I 'm not a expert, but you should use Ctypes in your uses clause. So you can use C types.
Code: [Select]
uses ....,ctypes;
(...)
MyVarInC := UInt32;
Other := PUInt16;

The types UInt32 and PUInt16 do not come from the ctypes unit instead they are aliases declared in the System unit. The types from the ctypes unit all have a c-prefix (or infix in case of pointer types), so it would be cuint32 and pcuint16 instead.
Title: Re: Casting an Array Of Pointers to PPointer for external C-Function
Post by: Zvoni on October 18, 2020, 02:55:20 pm
PD,
thx.
So i was actually pretty close, since my first try (which compiled!) was in fact the @MyVar[0], but it just looked weird to me, so i thought i'd better ask.
Title: Re: Casting an Array Of Pointers to PPointer for external C-Function
Post by: BlueIcaro on October 19, 2020, 08:17:06 pm
Hello, I 'm not a expert, but you should use Ctypes in your uses clause. So you can use C types.
Code: [Select]
uses ....,ctypes;
(...)
MyVarInC := UInt32;
Other := PUInt16;

The types UInt32 and PUInt16 do not come from the ctypes unit instead they are aliases declared in the System unit. The types from the ctypes unit all have a c-prefix (or infix in case of pointer types), so it would be cuint32 and pcuint16 instead.
[/quote]

Thanks I didn't know it.

/BlueIcaro
TinyPortal © 2005-2018