On 5 Sep 2019, at 17:41, Georg Hagn <georg.hagn@gmail.com> wrote:

I have to implemet following external structure (extrakt from the
german api Doku):

typedef struct {
    /**@brief MUST be always 2. */
    uint32_t version;

    /** @brief Pointer to KeyStore -- Verweis auf den KeyStore, see
EricGetHandleToCertificate(). */
    EricZertifikatHandle zertifikatHandle;

    /** @brief PIN f��r den KeyStore.*/
    const char *pin;

    /**
     * @brief MUST be NULL in my context
              Dieser muss ...
              In allen anderen F��llen muss hier NULL ��bergeben
werden. Der Parameter abrufCode
              besteht aus 2 x 5 Zeichen, die mit "-" verbunden sind.
              Beispiel: "K6FG5-RS32P"
     */
    const char *abrufCode;

} eric_verschluesselungs_parameter_t;

My Problem is, that i have to assign a NULL - value to the attribute abrufCode.
I have tried varies possibilities but I get always the error, that the
attribute abrufCode must have the value NULL.

" Extract from log-file:
019-09-05 17:08:52,257709[0x00007fe036a2f050] ERROR: F��r die
��bermittelte Datenart ist die Angabe eines Abrufcodes nicht zul��ssig,
daher muss f��r den Abrufcode der Wert NULL ��bergeben werden.
610001029"

How do I assign a NULL value to an attribute in a FFIExternalStructure?

The problem is not that is an structure but that is a char *, which is converted to a String in Pharo. 
Ideally, a nil should be mapped to NULL in this cases, but this is not working (never implemented).

Easiest workaround, just map abrufCode to void * instead char * (pointers are always same size). 

So you can have: 

myStryct abrufCode: ExternalAddress null. 
 
But of course, that will change the way you put the value there when *it is not* a NULL: 

myStryct abrufCode: ���hello��� utf8Encoded copyWith 0.

(The copyWith: 0 is to ensure the void * will receive something with proper \0 finalisation)

Esteban


Following my last attempt (extracted from the Pharo Booklet Colletion
"Calling Foreign Functions with Pharo May 31,2018")
I assign values not directly with the generated attributes but with
"api???" attributes.

FFIExternalStructure subclass: #ERiCVerschluesselungsParameter
   instanceVariableNames: ''
   classVariableNames: 'OFFSET_ABRUFCODE OFFSET_PIN OFFSET_VERSION
OFFSET_ZERTIFIKATHANDLE'
   package: 'Bajoras-ERiC'!


ERiCVerschluesselungsParameter class >> fieldsDesc [

   "ERiCVerschluesselungsParameter rebuildFieldAccessors"

   ^ #(
       uint32 version;
       ERiCZertifikatHandle * zertifikatHandle;
       char * pin;
       char * abrufCode;
   )
]

ERiCVerschluesselungsParameter >> initialize [

   self
       apiVersion: 2;
       apiAbrufCode: nil;
       apiPin: 'mySecret'.
]

ERiCVerschluesselungsParameter >> accessorMethods for: pin, version,
abrufCode, zertifikatHandle ("This method were automatically
generated")

ERiCVerschluesselungsParameter >> apiAbrufCode: aCode [

   | codeSize anAbrufCode |

   codeSize := 11.
   anAbrufCode := FFIExternalArray externalNewType: 'char' size: codeSize.
   1 to: codeSize do: [ :idx | anAbrufCode at: idx put: Character null ] .

   aCode ifNotNil: [
       aCode doWithIndex: [ :char :i | anAbrufCode at: i put: char ].
   ].

   self abrufCode: anAbrufCode.

]

ERiCVerschluesselungsParameter >> apiPin: aPin [

   | newPin |

   newPin := FFIExternalArray externalNewType: 'char' size: aPin size.
   aPin doWithIndex: [ :char :i | newPin at: i put: char ].

   self pin: newPin.
]


ERiCVerschluesselungsParameter >> apiVersion: aVersion [

   | cryptoVersion |

   cryptoVersion := 2.
   self version: cryptoVersion.

]

Thanks,
Georg Hagn