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? 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 |
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
|
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 <[hidden email]>: > > > > On 5 Sep 2019, at 17:41, Georg Hagn <[hidden email]> 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 > > |
Free forum by Nabble | Edit this page |