How to interpret the specifier of type objective-c (for example, returned by method_copyReturnType ())?

Given that I have a type specifier returned by method_copyReturnType (). In the GNU runtime supplied with GCC, there are various methods for working with a type specifier such as objc_sizeof_type() , objc_alignof_type() and others.

When using the Apple Runtime, such methods do not exist.

How can I interpret the type specifier string (for example, get the type size) using the Apple runtime without realizing the if / else or case key for myself?

[update]

I can not use the Apple Foundation.

+6
source share
2 answers

afaik, you need to bake this information in its binary format. just create a function that returns sizeof and alignof in the structure, supports the types you should support, then call this function (or class method) for information.

The program below shows that many of the primitives are just one character. Thus, the main part of the implementation of the function can be a switch.

 static void test(SEL sel) { Method method = class_getInstanceMethod([NSString class], sel); const char* const type = method_copyReturnType(method); printf("%s : %s\n", NSStringFromSelector(sel).UTF8String, type); free((void*)type); } int main(int argc, char *argv[]) { @autoreleasepool { test(@selector(init)); test(@selector(superclass)); test(@selector(isEqual:)); test(@selector(length)); return 0; } } 

and you can use this as a starting point:

 typedef struct t_pair_alignof_sizeof { size_t align; size_t size; } t_pair_alignof_sizeof; static t_pair_alignof_sizeof MakeAlignOfSizeOf(size_t align, size_t size) { t_pair_alignof_sizeof ret = {align, size}; return ret; } static t_pair_alignof_sizeof test2(SEL sel) { Method method = class_getInstanceMethod([NSString class], sel); const char* const type = method_copyReturnType(method); const size_t length = strlen(type); if (1U == length) { switch (type[0]) { case '@' : return MakeAlignOfSizeOf(__alignof__(id), sizeof(id)); case '#' : return MakeAlignOfSizeOf(__alignof__(Class), sizeof(Class)); case 'c' : return MakeAlignOfSizeOf(__alignof__(signed char), sizeof(signed char)); ... 
+2
source

I believe you are looking for NSGetSizeAndAlignment :

Gets the actual size and aligned size of the encoded type.

 const char * NSGetSizeAndAlignment ( const char *typePtr, NSUInteger *sizep, NSUInteger *alignp ); 

Discussion
Gets the actual size and aligned size of the first data type represented by typePtr , and returns a pointer to the position of the next data type in typePtr .

This is a Foundation function, not part of the underlying runtime, which probably does not allow it to be found.

UPDATE: Although you have not mentioned that you are using Cocotron, it is also available there. You can find it at the Cocotron Foundation, at NSObjCRuntime.m .

Obviously, this is much better than folding yourself, as you can trust it to always properly process the lines generated by your own runtime, in the unlikely event that the encoding characters need to change.

For some reason, however, it cannot process the digital elements of a method signature line (which, apparently, has something to do with offsets in memory). This enhanced version from Mike Ash will do this:

 static const char *SizeAndAlignment(const char *str, NSUInteger *sizep, NSUInteger *alignp, int *len) { const char *out = NSGetSizeAndAlignment(str, sizep, alignp); if(len) *len = out - str; while(isdigit(*out)) out++; return out; } 
+5
source

Source: https://habr.com/ru/post/905288/


All Articles