Re: Objective-C++ and NSInvocation (or IMP)
Re: Objective-C++ and NSInvocation (or IMP)
- Subject: Re: Objective-C++ and NSInvocation (or IMP)
- From: "E. Wing" <email@hidden>
- Date: Wed, 30 May 2007 16:08:23 -0700
Thanks for all the replies. I learned a lot.
On 5/30/07, Scott Ribe <email@hidden> wrote:
I thought about evil things such as using placement-new syntax on locally
malloc'd memory at the creation of the invocation, combined with explicit
destructor call and free at dealloc of the invocation, so that for instance
things like smart pointers could be used and work correctly when the
creation and invocation occur on different threads. However, I did not go
down that path ;-)
<snip>
I'm not doing anything so ambitious. I have some existing code that
uses a template functor implementation (similar to
http://www.tutok.sk/fastgl/callback.html). It works for C function
pointers and C++ functors. Now that I'm using Objective-C, I'm trying
to figure out how I can use intermix Obj-C within this framework
without totally rewriting all the underlying components that already
use this interface. The work-around is just to add a layer of
indirection and write C functions and stuff Objective-C object
pointers as void* parameters which is kept around for unanticipated
cases like this and then invoke the specific Obj-C methods I actually
wanted. But it's a little tedious and inelegant and it seemed
unnecessary considering all the interesting things Obj-C can do.
On 5/29/07, John Stiles <email@hidden> wrote:
I'd guess that (among other potential issues) NSInvocation does not know
how to call a C++ copy-constructor.
As a workaround, did you try passing "const std::string&" instead of
"std::string"? This is likely to work OK, since it's just passing a
reference instead of creating a copy.
So I gave it a try and pass-by-const-reference didn't work.
It didn't like my setArgument.
[myInvocation setArgument: &some_str atIndex: 2];
*** Uncaught exception: <NSInvalidArgumentException> parameter index 2
not in range (-1,2)
Trying the getArgumentTypeAtIndex also throws an exception:
*** Uncaught exception: <NSInvalidArgumentException> ***
-[NSMethodSignature getArgumentTypeAtIndex:]: index out of bounds
On 5/30/07, Alastair Houghton <email@hidden> wrote:
If you were to pass a *pointer* to an std::string instead, it might
then work. I doubt a reference would work since I don't think
there's even an ObjC type code for a C++ reference.
If you're interested, you might try calling -getArgumentTypeAtIndex:
on your NSMethodSignature to see what type information is actually
present for the arguments you're having trouble with.
For just regular std::string, getArgumentTypeAtIndex returns:
{basic_string<char,std::char_traits<char>,std::allocator<char>
={_Alloc_hider=*}}
I'm not sure what I was expecting. I guess I'm surprised it had that
much information at all. But alas, it doesn't work.
I tried the pointer solution, and that seemed to work. Its argument type is:
^{basic_string<char,std::char_traits<char>,std::allocator<char>
={_Alloc_hider=*}}
Unfortunately, my usage scenario deals with working with some
preexisting code and I don't think the pointer solution will be a
practical solution for me.
As far as the IMP approach goes, it *will* work, but you'll have to
cast your IMP to a pointer with the correct type. So it should look
like this:
std::string (*imp)(id, SEL, std::string, std::string) = [myObject
methodForSelector:@selector(appendString:withString:)];
imp(myObject, @selector(appendString:withString:), "foo", "bar");
This worked perfectly with my test cases and seems compatible with my
usage scenario. Thank you. Since my code goes through all templated
stuff, I know the argument types and number of arguments at compile
time so I can actually make this cast in a general enough way.
Obviously NSInvocation is a more general way to call arbitrary ObjC
methods.
Can you elaborate on this? I still haven't gotten a sense of when/why
to use NSInvocation over IMP or vice-versa. They seem equivalent to me
with respect to invoking methods. The major difference is I found IMP
a little more confusing partly due to the different platform specific
ways of getting an IMP (e.g. methodFor:, methodForSelector:,
class_getInstanceMethod, objc_msg_lookup.
Thanks,
Eric
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden