<div dir="ltr"><div><div><div><div><div><div><div><div><div>Hi,<br></div>the title is a bit complex, but I'll try to explain what I am after.<br><br></div><div>I need to pass a pointer to an atomic data because it is an output of a function.<br></div><div>But this atomic data is a named type (a typedef), and I want to preserve the name for several reasons:<br></div><div>- the typedef might evolve in another version of the library<br></div><div>- the typedef might be machine dependent (like size_t or unsigned long)<br></div><br></div>In VW, it's simple enough, i define the typedef directly, then use malloc and free like this:<br></div></div><br><span style="font-family:monospace,monospace">H5Type>>getPadding<br>    | lsb msb |<br>    [lsb := API H5T_pad_t malloc.<br>    msb := API H5T_pad_t malloc.<br>    API H5Tget_pad: handle with: lsb with: msb.<br>    lsbPadCache := lsb contents.<br>    msbPadCache := msb contents]<br>            ensure: <br>                [lsb isNil ifFalse: [lsb free].<br>                msb isNil ifFalse: [msb free]]<br><br>H5T_pad_t<br>    <C: typedef enum __H5T_pad_t H5T_pad_t><br><br></span></div><span style="font-family:monospace,monospace">H5Interface>>H5Tget_pad: type_id with: lsb with: msb<br>    <C: herr_t H5Tget_pad(hid_t type_id, H5T_pad_t * lsb, H5T_pad_t * msb)><br>    ^self externalAccessFailedWith: _errorCode</span><br><br></div>In Squeak, I have used this feature of ExternalStructure so as to alias another type (and have a sort of typedef):<br><br><a href="https://stackoverflow.com/questions/49783882/how-one-deals-with-typedefs-in-squeak-ffi/49798663#49798663">https://stackoverflow.com/questions/49783882/how-one-deals-with-typedefs-in-squeak-ffi/49798663#49798663</a><br><br>So I create the class:<br><br><pre><code>ExternalStructure subclass: #'H5T_pad_t'
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'FFI-Tests'</code></pre>Since it is an enum, I can use methods for accessing enum values<br><br></div><div><span style="font-family:monospace,monospace">H5T_pad_t class>>H5T_PAD_ERROR ^-1</span><div><span style="font-family:monospace,monospace">H5T_pad_t class>>H5T_PAD_ZERO  ^0</span></div><div><span style="font-family:monospace,monospace">H5T_pad_t class>>H5T_PAD_ONE   ^1</span></div><div><span style="font-family:monospace,monospace">H5T_pad_t class>>H5T_PAD_BACKGROUND ^2</span><div><span style="font-family:monospace,monospace">H5T_pad_t class>>H5T_NPAD      ^3</span></div></div><br></div><div><div>And I can define the fields with the knowledge that most C implementation will use an int to store the enum:<br><br></div><span style="font-family:monospace,monospace">H5T_pad_t class>>fields ^#( value 'long')</span><br><br></div><div>Then I can generate #value and #value: via <span style="font-family:monospace,monospace">H5T_pad_t defineFields</span> and write:<br></div><div><br><span style="font-family:monospace,monospace">H5Type>>getPadding<br>    | lsb msb |<br>    lsb := H5T_pad_t new.<br>    msb := H5T_pad_t new.<br>    API H5Tget_pad: handle with: lsb with: msb.<br>    lsbPadCache := lsb value.<br>    msbPadCache := msb value<br><br>H5Interface>>H5Tget_pad: type_id with: lsb with: msb<br>    <cdecl: Herr_t 'H5Tget_pad'( Hid_t H5T_pad_t * H5T_pad_t * )><br>    ^self externalCallFailed<br></span><br></div><div>H5T_pad_t new does the right thing: it allocates memory in a ByteArray, and store it in handle inst. var., something like <span style="font-family:monospace,monospace">handle := ByteArray new: 4</span><br><br></div><div>But then, the generated accessors not so: they consider that a non pointer atomic type does not require an intermediate memory buffer, because FFI can transform directly a Smalltalk atomic object (Integer/Boolean/Character/Float).<br><br></div><div>    value  ^handle<br></div><div>    value: anObject handle := anObject<br><br>They return the buffer instead of the content.<br></div><div><br></div><div>This is completely missing the point: the only reason I have to create an instance of such atomic type is to pass a reference (pointer) to the data, else, I can just use one of the enum accessors and pass the integer value directly:<br><br><span style="font-family:monospace,monospace">H5TInteger>>setPadZero<br><span style="font-family:monospace,monospace">    </span>API <span style="font-family:monospace,monospace">H5Tset_pad: handle with: H5T_pad_t <span style="font-family:monospace,monospace">H5T_PAD_ZERO</span> with: </span><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">H5T_pad_t <span style="font-family:monospace,monospace">H5T_PAD_ZERO</span></span></span><br><br>H5Interface>>H5Tset_pad: type_id with: lsb with: msb<br>    <cdecl: Herr_t 'H5Tset_pad'( Hid_t H5T_pad_t H5T_pad_t )><br>    ^self externalCallFailed</span><br><br></div><div>what I want is this:<br><br></div><div>    value ^handle longAt: 1<div>    value: anObject  handle longAt: 1 put: anObject<br><br></div><div>It's very simple to change because such generation already exists for accessing structure fields.<br><br></div><div>It's very logical to change, because consistent with the behavior of new and possible intentions of allocating an instance of such type as I showed above.<br></div><div><br></div><div>However, I absolutely don't know the impact of such change on existing code base.<br><br></div><div>1) the alias feature is not documented, has no test and no example (with accessors)<br></div><div>2) I don't know an easy way to scan the existing code base<br>   (SqueakSource, ss3, SmalltalkHub, HPI, etc...)<br><br></div><div>Has anyone got a better idea, or knows a library that would be broken, or have a strong opinion against this change for whatever reason?<br></div><br></div><div>I'll understand the absence of answer as a "carte blanche" to proceed.<br><br></div><div>Nicolas<br></div></div></div>