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