<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        
                                        
                                            
                                        
                                        
                                        > <span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">BTW: "char *libs[n]" doesn't work and won't compile ;)</span><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Hmm... what could the FFI Call spec look like for:</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">static size_t _sqo_lib_paths(size_t const n, char (*libs[n]))</span><br style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Maybe like this:</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">cdeclSqoLibPaths: n with: libs</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">    <cdecl: size_t '_sqo_lib_paths' (size_t char**)></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Well, calling "self cdeclSqoLibPaths: 0 with: nil" would return the required size n for libs. Then you could construct a byte array with "n * ExternalType size_t </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">byteSize</span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">" bytes so that the library can store all the pointers...</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">n := self </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">cdeclSqoLibPaths: 0 with: nil.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">libs := ByteArray new: n * ExternalType size_t byteSize.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">self cdeclSqoLibPaths: n with: libs.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Should work. Alternatively, you can use external memory, not Squeak's object memory:</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">n := self </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">cdeclSqoLibPaths: 0 with: nil.</span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">libs := ExternalAddress allocate: n * ExternalType size_t byteSize.</span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">self cdeclSqoLibPaths: n with: libs.</span></div></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">In both cases, you would need to put it into an object to start reading the data. For example, an ExternalData ... or a fitting ExternalTypeAlias:</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">data := ExternalData fromHandle: libs type: ExternalType void asPointerType.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Now it get's tricky. At the moment, we cannot tell ExternalData about the "char**" type. So, "data size: n; do: [:each | ... ]" will not work. We can, however, do it manually:</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">strings := (1 to: n) collect: [:index |</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">   | data |</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">   data := </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">libs p</span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">ointerAt: (index-1 * ExternalAddress wordSize)+1.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px">   data := ExternalData fromHandle: data type: ExternalType string "char*".</span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px">   data fromCString].</span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px"><br></span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">libs class == ExternalAddress ifTrue: [libs free].</span><br></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px">But then we have to watch out for the pointer sizes on our own.</span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px"><br></span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px">Maybe we can help here to improve the workflow and avoid redundant code.</span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Best,</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Marcel</span></div><div class="mb_sig"></div>
                                        
                                        <blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 15.06.2020 15:00:58 schrieb Tobias Pape <das.linux@gmx.de>:</p><div style="font-family:Arial,Helvetica,sans-serif"><br>> On 15.06.2020, at 14:52, Marcel Taeumel <marcel.taeumel@hpi.de> wrote:<br>> <br>> > Hello, C99:<br>> <br>> So, "char (*libs[n])" would be equivalent to "char *libs[n]", which is an array of n pointers, each pointing to a character ... which is a null-terminated string, I suppose? Like "char **argv" or "char *argv[]" ... but with n<br><br>It is an array of n char-pointers (in fact, C-Strings), and n refers to an earlier variable in the parameter list...<br><br>BTW: "char *libs[n]" doesn't work and won't compile ;)<br>-t<br><br>> <br>> Best,<br>> Marcel<br>>> Am 15.06.2020 14:34:02 schrieb Tobias Pape <das.linux@gmx.de>:<br>>> <br>>> <br>>> > On 15.06.2020, at 14:24, Jakob Reschke wrote:<br>>> > <br>>> > <br>>> > Marcel Taeumel schrieb am Mo., 15. Juni 2020, 13:22:<br>>> > <br>>> > - Accept type names such as "int **" or "int[][]" in FFI-call specs and struct-field spec<br>>> > <br>>> > One further note: int[][] is not valid C in parameter types. Only the first [] can be without length, and is equivalent to a pointer. So char*argv[] is the same as char**argv. Valid parameter type examples: int a[][3], int b[][2][3]. These are like int(*a)[3] and int(*b)[2][3] if I am not mistaken.<br>>> > <br>>> <br>>> Hello, C99:<br>>> <br>>> /* Find all paths that may contain dynamic libraries.<br>>> * Returns their count. libs may be NULL to get allocation size<br>>> */<br>>> static size_t _sqo_lib_paths(size_t const n, char (*libs[n]))<br>>> {<br>>> /*...*/<br>>> }<br>>> <br>>> ;)<br>>> <br>>> -t<br>>> <br>> <br><br><br><br></das.linux@gmx.de></marcel.taeumel@hpi.de></div></blockquote></div>