-->

MacRuby pointer, referencing, dereferencing when u

2019-07-15 10:57发布

问题:

On MacRuby Pointer to typedef struct, I learnt how to dereference a pointer created with

x=Pointer.new_with_type
...
==> use x.value, or x[0]

Works a treat !

Now I want to learn what I believe to be the "opposite". I'm trying to use this API.

OSStatus SecKeychainCopySettings (
   SecKeychainRef keychain,
   SecKeychainSettings *outSettings
);

Second parameter must be a Pointer. But I never manage to get the real outSettings of the keychain opened, I only get the default settings.

framework 'Security'
keychainObject = Pointer.new_with_type('^{OpaqueSecKeychainRef}')
SecKeychainOpen("/Users/charbon/Library/Keychains/Josja.keychain",keychainObject)

#attempt #1
settings=Pointer.new_with_type('{SecKeychainSettings=IBBI}')
SecKeychainCopySettings(keychainObject.value, settings)
p settings.value
#<SecKeychainSettings version=0 lockOnSleep=false useLockInterval=false lockInterval=0>

#attempt #2
settings2=SecKeychainSettings.new
result = SecKeychainCopySettings(keychainObject.value, settings2)
p settings2
#<SecKeychainSettings version=0 lockOnSleep=false useLockInterval=false lockInterval=0>

The settings of the Keychain opened should read

#<SecKeychainSettings version=0 lockOnSleep=true useLockInterval=true lockInterval=1800>

What am I missing ?

回答1:

Got it ! The doc to SecKeychainCopySettings mentions

outSettings On return, a pointer to a keychain settings structure. Since this structure is versioned, you must allocate the memory for it and fill in the version of the structure before passing it to the function.

So we can't just create a Pointer to SecKeychainSettings. We must set the version of the Struct that is pointed by the pointer to to something.

settings=Pointer.new_with_type('{SecKeychainSettings=IBBI}')
#settings[0] dereferences the Pointer
#for some reason, settings[0][0]=1 does not work, nor settings[0].version=1
settings[0]=[1,false,false,0]
#we are redefining the complete SecKeychainSettings struct
# [0]=version [1]=lockOnSleep [2]=useLockInterval [3]=lockInterval
result = SecKeychainCopySettings(keychainObject.value, settings)
p settings
=> #<SecKeychainSettings version=1 lockOnSleep=true useLockInterval=false lockInterval=300> irb(main):019:0>