Hi Gerry,

I think the point of Tomaz is that an FFI method can only have a single 
#ffiCall: statement.
In your example, what you can do is to split your method in two methods:

First a method with the mapping (following the idea of Tomaz but using libc)

FFITutorial>>getHostNameInto: hostName ofLenght: length
>     ^self ffiCall: #( int gethostname(char *hostName, int length) ) library: 
> 'libc.so.6'. 

And then have a second method that calls this one:

FFITutorial>>getHostName

       | nameBuffer |      

nameBuffer := ByteArray new: 256. 

self getHostNameInto: nameBuffer ofLenght: 256.

^nameBuffer asString

Notice that converting the byte array buffer to string will only work by chance 
if the called function returns characters encoded in ascii.
In Pharo strings are Unicode characters where each character is a unicode 
code-point.
The best thing is to read the documentation of the library and check the 
encoding of the string that is put in the buffer to decode it accordingly, for 
example from utf8.

G


> El 29 nov 2021, a las 0:56, Gerry Weaver <ger...@compvia.com> escribió:
> 
> Hi,
> 
> Thanks for the example. Unfortunately, it doesn't work on Linux.
> 
> Thanks,
> Gerry
> 
> 
> From: Tomaž Turk <tomaz.t...@ef.uni-lj.si>
> Sent: Sunday, November 28, 2021 11:39 AM
> To: Any question about pharo is welcome <pharo-users@lists.pharo.org>
> Subject: [Pharo-users] Re: uFFI provide buffer to C
>  
> Hi,
> 
> try with this:
> 
> FFITutorial>>getHostNameInto: hostName ofLenght: length
>     ^self ffiCall: #( int gethostname(char *hostName, int length) ) library: 
> 'Ws2_32.dll'. "... on Windows"
> 
> From Playground, you can then do:
> 
> | name len |
> len := 50.
> name:= ByteArray new: len.
> FFITutorial new getHostNameInto: name ofLenght: len. 
> name inspect.
> 
> I hope this helps.
> 
> Best wishes,
> Tomaz

Reply via email to