[Pharo-users] uFFI Structure Problem

Georg Hagn georg.hagn at gmail.com
Mon Sep 9 11:16:37 EDT 2019


Thank you Esteban for your fast answer.

1) NULL Pointer assignment:
I have implemented your advise, and changed the attribute "abrufCode"
to "ExternalAddress null";
    >> fieldDesc #(myStruct uint32 version;  ...  void * abrufCode; )
The Structure has a NULL pointer assigned!? (see Inspector on MyStruct
"MyStruct (
version: 2
zertifikatHandle: (void*)@ 16r7F8400000001
pin: (char*)@ 16r7F84FB7FE5A0
abrufCode: (void*)@ 16r00000000
)"

But the problem is the same. I get the error: "attribute abrufCode
must have the value NULL." Any ideas?

2) coercing problem:
In my various tries I changed the whole structure to ExternalAddress
null. (In some circumstances I have to set the whole Structure to
NULL)
Now I got an coercing error. I think, because ExternalAddress is not a
FFIExternalStructure.
"
^ self ffiCall: #(int BearbeiteVorgang(String daten, String version,
int flags,  ExternalAddress * druck, MyStruct * crypto, TransferHandle
* transfer, RueckgabeHandle * rueckgabe, RueckgabeHandle *
serverantwort)).
"
Is it possible, NOT to decide between (here 4: druck and crypto can be
either Structures or NULL) ffi-calls?

Thank you, Georg








Am Do., 5. Sept. 2019 um 16:30 Uhr schrieb Esteban Lorenzano
<estebanlm at gmail.com>:
>
>
>
> On 5 Sep 2019, at 17:41, Georg Hagn <georg.hagn at 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
>
>



More information about the Pharo-users mailing list