Recent

Author Topic: Casting an Array Of Pointers to PPointer for external C-Function  (Read 1219 times)

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
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)?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Casting an Array Of Pointers to PPointer for external C-Function
« Reply #1 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/Pascal_for_C_users

/BlueIcaro

PascalDragon

  • Hero Member
  • *****
  • Posts: 5469
  • Compiler Developer
Re: Casting an Array Of Pointers to PPointer for external C-Function
« Reply #2 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.

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: Casting an Array Of Pointers to PPointer for external C-Function
« Reply #3 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.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Casting an Array Of Pointers to PPointer for external C-Function
« Reply #4 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