On 22 Feb 2014, at 00:12, Ken Thomases <k...@codeweavers.com> wrote:

> On Feb 21, 2014, at 3:17 PM, jonat...@mugginsoft.com wrote:
> 
>> So I want to be able to send the same message to any class and get an 
>> appropriate void* pointer.
> 
> There's no one representation of its content, so there's no way for any 
> recipient of a supposed "pointer to that content" (however that might be 
> obtained) to interpret the pointer.
Not so.
The pointer is ultimately passed as a vararg along with a Mono method 
representation as part of a Mono method invocation.
The Mono method representation includes type info for its parameters.
Hence it can cast and deference a void* pointer appropriately.

This method is used to query C#/CLR Dictionary <TKey, TValue> for a given key 
using the embedded MONO C API:

 - (BOOL)containsKey:(id)key
{
    BOOL containsKey = NO;
    
    // TODO: use -confromsToProtocol?
    if ([key respondsToSelector:@selector(monoObject)] && [key 
respondsToSelector:@selector(monoValue)]) {
        
        // form the method name
        NSString *monoArgumentTypeName = [[DBTypeManager sharedManager] 
monoArgumentTypeNameForMonoObject:[key monoObject]];
        NSString *methodName = [NSString stringWithFormat:@"ContainsKey(%@)", 
monoArgumentTypeName];
        
        // invoke the method
        MonoObject *monoObject = [self invokeMonoMethod:[methodName UTF8String] 
withNumArgs:1, [key monoValue]];
        containsKey = DB_UNBOX_BOOLEAN(monoObject);
    } else {
        [NSException raise:@"Invalid key" format:@"Key %@ must respond to 
-monoObject and -monoValue", key];
    }
    
    return containsKey;
}

- (MonoObject *)invokeMonoMethod:(const char *)methodName 
withNumArgs:(int)numArgs, ... {
        va_list va_args;
        va_start(va_args, numArgs);
        
        MonoObject *ret = DBMonoObjectInvoke(_monoObj, methodName, numArgs, 
va_args);
        
        va_end(va_args);
        
        return ret;
}

In the above if key is an NSNumber containing a 5 then  [key monoValue] returns 
a pointer to a 5.
If the key is an NSString then  [key monoValue] returns a pointer to a 
monoObject representing the string.

> 
> If you have some specific representation in mind, then don't use NSNumber.  
> Use a custom class wrapping the specific representation you want to use.
The custom class would simply be a dupe of NSNUmber + 1 method.
My original category solution seems simpler. 
> 
> 
>> This usage pattern, within a generated code environment too, makes the 
>> imposition of an lvalue that I can take an address from undesirable.
> 
> However undesirable it may be, it's a consequence of you wanting an address 
> for things which don't have an address.  The thing has to be stored, at least 
> temporarily, in storage which has a proper address (and a predictable size 
> and semantic interpretation).
This is what the code in my OP does.

> 
>> Plus it also needs to be an NSNumber, not a custom NSObject subclass.
> 
> Why?
I am not in control of the types on which I have to operate.

> 
> If you really, really want to try to do this _and_ you can pick a single 
> in-memory representation for all NSNumber content values, you could do 
> something similar to what NSString does for -UTF8String.  You'll notice that 
> that method's returned string has the lifetime of an autoreleased object, not 
> the original string object.  I believe that it just creates an autoreleased 
> NSData holding the UTF-8-encoded bytes and returns that NSData's -bytes.  So, 
> you'd do something like:
I think the code in the OP does this.

Thanks for looking

Jonathan
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to