API returning a C Array - how to read Objc.protocol_copymethoddescriptionList?

This is a follow-up to my question about reading Objc_message_descriptions.
On the general objC lib, this works fine now.

But then there’s there method protocol_copyMethodDescriptionList which gives me hard times.
It returns a C array of objc_message_descriptions.
These are by definition made of a Selector As Ptr and Types as CString.

I can easily read the Selector and fetch its name by calling protocol_getname by getting the array via a Core.Memoryblock and reading its ptrvalue(q).
The next 4 Bytes must be the types CString, but a fixed length of 4 Bytes would by starnge for a CString. So I guess it must be delivered as a Ptr too.
But I cannot succesfully read it. I tried several ways but must have some bug in my thinking. Do you have any idea what mistake I make?

Here’s the current implementation:

Function InstanceMethods() As objc_method_description() dim minstancemethods() as objc_method_description // This is the named struct: a Ptr and a CString dim arrayPtr as ptr dim count as uinteger arrayPtr = ObjectiveCRuntime.protocol_copyMethodDescriptionList (id, false, true, count) // just getting the InstanceMethodDescriptions here. if arrayPtr <> NIL then dim mb as xojo.Core.MemoryBlock = CoreMemoryBlockExtension.fromPtrArray (arrayptr, count * 2) // times 2 because it returns count * 2 Ptr sized values. for q as uinteger = 0 to count*2 -1 step 2 dim mymethoddescription as objc_method_description mymethoddescription.Selector = mb.pointer(q) // Until here everything's fine dim mytypesMB as new xojo.Core.MemoryBlock (mb.pointer (q+1)) // Pointer is a Memoryblock extension returning an Ptrvalue of the MB at position index * Integersize ( Integersize gives 4 on 32 bit and 8 on 64bit systems) // If I try to fetch what I think to be the ptr to types this way (without limitation), I get an enormous chunk of memory as result. // But how would I determine the size of a CString in advance? // and the memoryblock returned starts "c12@0:4@8:@04.self.performselector". So it's wrong. mymethoddescription.Types = mytypesMB.CStringValue(0) minstancemethods.Append mymethoddescription next MacOSLibSystem.free arrayptr // at least freeing seems to work now. end if return minstancemethods End Function

EDIT: Had a wrong offset in the method and updated the results

You do not - and it is not necessary. CStrings are terminated by a NULL char.

That’s the code I use:

[code]Structure objc_method_description
SEL As Ptr
types As CString
End

Declare Sub free Lib “libSystem.dylib” (p As Ptr)
Declare Function protocol_copyMethodDescriptionList Lib “libobjc.dylib” (protocol As Ptr,
isRequiredMethod As Byte, isInstanceMethod As Byte, ByRef outCount As UInt32) As Ptr

Dim descriptions() As objc_method_description

For isRequired As Integer = 1 DownTo 0
For isInstance As Integer = 1 DownTo 0
Dim count As UInt32
Dim mb As Ptr = protocol_copyMethodDescriptionList(ProtocolPtr, isRequired, isInstance, count)
For i As Integer = 0 To count - 1
Dim desc As objc_method_description = mb.objc_method_description(i * objc_method_description.Size)
descriptions.Append(desc)
Next
free(mb)
Next
Next

For i As Integer = 0 To descriptions.Ubound
Dim p As Ptr = descriptions.SEL
Dim types As CString = descriptions.types
Next
[/code]

Wow! Argh! Sure! I missed the description.size property. That’s why I made it to work initially for the first but not concurrent properties – and been trying around for days … ;(
Thanks a lot, Eli!