🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.next.programmer
Article #536

Re: Calling methods from procedures?

#536
From: Gregory H. Anderson
Date: Tue, 11 Aug 1992 15:10
62 lines
3102 bytes
In article <1992Aug10.145106.2021@cs.uno.edu> jrscs@uno.edu writes:
> Can anyone offer some help in solving the following problem:
> 
>  From a regular C procedure p located in a regular C file f1.c, I would
>  like to "call" an Obj-C instance method m located in the file f2.[hm].
>  Ideally, I would like to say [ self m ] where self is the object that
>  I would like to message; but, of course, self is not known in f1.c.  In
>  fact, I couldn't even get self to be recognized in some regular C
>  procedures in f2.m.  So, is there an easy work-around to this problem ?
> 
> Thanks in advance.

There is a fun, and only _slightly_ illegal way to do this. I haven't  
actually tried it, but theoretically it should work. If it works, I take  
all the credit. If your machine explodes, I'll deny I ever wrote this.

Ultimately, all Objective-C messages are mapped by the compiler to one of  
three functions: objc_msgSend(), objc_msgSendSuper(), or objc_msgSendv().  
Super doesn't matter in your example, so fuhgedaboudit. Send() is for  
fixed argument lists; Sendv() is for variable arguments (like printf).

You can get the function pointer where the method actually lives with a  
call to [self methodFor:(SEL)aSelector], which returns a (*func)(). If you  
only have a method name, use [self methodFor:@selector(myMethod:)].

The other important thing to know is that each Objective-C message has two  
other hidden arguments: self (the id of the object) and _cmd (the selector  
for the method). self is a (char *), _cmd is an unsigned long. These are  
ALWAYS prepended to your argument list when the underlying c function gets  
called by objc_msgSend().

With that information as a background, here's _all_ 8^) you need to do:

1. In the c file, export some GLOBAL static space to hold an id (char *),  
an unsigned long, and a function pointer.

2. Before dropping into your c routine, assign appropriate values to each  
of these variables from a method within the object you will be calling  
back to:

- setCallbackInfo
	{
	callback_id = self;
	callback_cmd = @selector(callbackMethod:);
	callback_pointer = [self methodFor:@selector(callbackMethod:)];
	return self;
	}

3. Call your c function. Within it, you should now be able to say:

	(*callback_pointer)(callback_id, callback_cmd, method args...)

You might want to prototype this function so the compiler doesn't promote  
variables against your wishes.

Let me know how it turns out.

--
Gregory H. Anderson          | "We're very tolerant around here,
Benevolent Dictator-for-Life |  being only amateurs ourselves."
Anderson Financial Systems   | - Tortoise (Godel, Escher, Bach)
greg@afs.com  (Nextmail OK)  | 
Technical Details
Message-ID: <1992Aug11.151027.1192@afs.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!psinntp!afs!greg
References: <1992Aug10.145106.2021@cs.uno.edu>

Show Full Headers
Complete Article Headers
Newsgroups: comp.sys.next.programmer
Path: arc1-ca.pugleaf.net!sparky!uunet!psinntp!afs!greg
From: greg@afs.com (Gregory H. Anderson)
Subject: Re: Calling methods from procedures?
Message-ID: <1992Aug11.151027.1192@afs.com>
Sender: greg@afs.com
Reply-To: greg@afs.com
References: <1992Aug10.145106.2021@cs.uno.edu>
Date: Tue, 11 Aug 1992 15:10:27 GMT
Lines: 62