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
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
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@gmail.com>:
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
participants (2)
-
Esteban Lorenzano -
Georg Hagn