> On 5 Sep 2019, at 17:41, Georg Hagn <georg.h...@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
> 

Reply via email to