Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,557
6,058
Is there any equivalent in Obj-C to NSSelectorFromString, but for getting function pointers from NSStrings?

Specifically I'd like to just have a means of typing CG commands into a text field and have them rendered in a view next to it as you type. I realize I could parse the text for the functions and look them up, but that requires me copying every function in CG, and when more get added later, I'd have to support those, too. I was hoping to have something simple where it just grabs the function name and can look up the function pointer.

Thanks!
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
I doubt this is possible at run time as there is no guarantee that the function name is retained and non-mangled by the compiler. You could make it possible via some convoluted code that saved a pre-determined set of function names and NSStrings into a data structure. This would work as the compiler would deal with the name/mangling. But you would need to know the names of all the functions and all their argument types and deal with storing these types (different for different functions) into a data structure (NSMutableDictionary say). So you would need a custom object to contain the pointer too. This is going to get messy quickly!
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
Is there any equivalent in Obj-C to NSSelectorFromString, but for getting function pointers from NSStrings?

Specifically I'd like to just have a means of typing CG commands into a text field and have them rendered in a view next to it as you type. I realize I could parse the text for the functions and look them up, but that requires me copying every function in CG, and when more get added later, I'd have to support those, too. I was hoping to have something simple where it just grabs the function name and can look up the function pointer.

Thanks!

That kind of thing is really, really dangerous.

If you insist, I'd write some code that parses a header file, and generates the code that you want it to generate.
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,557
6,058
That kind of thing is really, really dangerous.

Thanks - that didn't occur to me until just now.

I guess I'll just parse the code and call the corresponding functions - it'll be a lot safer because I'm guaranteeing that arbitrary code can't be executed.

As I flesh out this idea in my head, I'm realizing this could be an easy app to sell to other developers in the MAS. Probably won't be as profitable as Battery Status, but I imagine there's probably other developers who would want a quick and dirty app to test CG code as they write it, too.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,739
8,415
A sea of green
Having the function pointer won't help you determine the parameters, their type, or their order. There needs to be additional information provided to your your program, otherwise you won't be able to invoke the function whose pointer you have with the parameters it needs.

See this:
http://en.wikipedia.org/wiki/Libffi

Try this shell command:
Code:
ls -ld /usr/lib/*ffi*
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,557
6,058
Having the function pointer won't help you determine the parameters, their type, or their order. There needs to be additional information provided to your your program, otherwise you won't be able to invoke the function whose pointer you have with the parameters it needs.

I'd be able to gather type, order, and how many based on what the user types trying to pass in. No idea what would happen if I tried passing in the wrong number of arguments... Probably nothing too bad? If I pass in too many arguments, they might spew into the stack, but that stuff would just get written over when the stack grows to that spot, and if I pass in too few then the function will end up with garbage / initialized data... Potentially fatal if it wanted a pointer, but other than that I can't see it going all that badly...

I'm thinking I'll just use string comparisons, though. It'll keep everything simple and safe.
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
No idea what would happen if I tried passing in the wrong number of arguments... Probably nothing too bad?

Segmentation fault of undefined behaviour probably, it would also be true for the wrong type of argument. Normally that would not even compile.
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,557
6,058
Segmentation fault of undefined behaviour probably, it would also be true for the wrong type of argument. Normally that would not even compile.

If I'm using function pointers I don't think there's any way for the compiler to catch that I'm passing the wrong number of functions. Or at least I don't think there is.
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
If I'm using function pointers I don't think there's any way for the compiler to catch that I'm passing the wrong number of functions. Or at least I don't think there is.

Yes, that was my point. I said "normally" to mean, under normal circumstances you write the code, then compile it.

Edit: But you could write your own runtime checks while you parse, of course by that time you have basically written your own programming language on top of CG.
 
Last edited:

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,557
6,058
Yes, that was my point. I said "normally" to mean, under normal circumstances you write the code, then compile it.

Edit: But you could write your own runtime checks while you parse, of course by that time you have basically written your own programming language on top of CG.

Right... amoungst the things considered was the possibility of wrapping all the C functions in an obj-c class as methods and then using NSSelectorFromString... but then that involves also changing what the user types into things resembling selectors instead of functions, plus there's the fact that most CG functions already have equivalent obj-c methods.

IE, you could use a CG function to set a fill color and another CG function to fill a path, or you could call set fill color on an NSColor and use the fill command on an NSBezierPath.
 

bearda

macrumors 6502a
Dec 2, 2005
502
175
Roanoke, VA
You could do it in pure C by using the preprocessor to populate a table with function pointers and their corresponding function name strings and casting everything to a void*. No header file parsing required, the preprocessor already has it parsed by the time you're compiling, You'd have to do a lookup on the table with every attempted call, you'd have no type checking, and it would be one hell of an ugly hack, though.

I wouldn't suggest it.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,739
8,415
A sea of green
If I'm using function pointers I don't think there's any way for the compiler to catch that I'm passing the wrong number of functions. Or at least I don't think there is.

Pointers to functions can declare the function as having specific parameter types, exactly the same as you would declare a function itself. Here's an example for the sigaction() function:
Code:
             union {
                     void    (*__sa_handler)(int);
                     void    (*__sa_sigaction)(int, struct __siginfo *, void *);
             } __sigaction_u;                /* signal handler */
The member __sa_handler is a pointer to a function taking one int parameter and returning void (i.e. returning nothing). The member __sa_sigaction is a pointer to a function taking an int parameter, a struct __siginfo pointer parameter, and a void-pointer parameter (total of 3 parameters).

See the man page for sigaction for more details.


The C compiler needs static (i.e. compile-time) declarations of function parameters and types. If it doesn't have that information, it will issue a warning.

However, you can also give the C compiler wrong information, and it will compile and link it. The program may fail in strange or spectacular ways at runtime, or it may have no effect. For example, try declaring the puts() function like this:
Code:
int puts( const char * str, int len );
Be sure to NOT have a #include <stdio.h> in your source file. Run it, see what happens.

Then try this and see what happens:
Code:
int puts( int len, const char * str );


Note that C++ doesn't have this problem, because it "mangles" function names (at least ones outside of the "C" namespace) to contain information about the type and order of parameters. Look up C++ name-mangling; it's well known.


If you really want to do this project, then you need to learn how interpreters work, because that's what you're doing: writing an interpreter for CG functions. Among other things, that means you have to parse and interpret some fairly complex C expressions, which tends to put the complexity of such an interpreter on about the same level as writing a C compiler.

One reason I pointed you to libffi is because it's used by interpreters like Python whose source is available. The best way to learn how interpreters work is by studying an existing one. The simplest interpreter I know of is Forth's "outer" interpreter. It works like this:
1. Take the next blank-delimited word.
2. Look it up in the dictionary (mapping from name to action).
3. If found, execute the action.
4. If not found, try converting the word to a number.
5. If word converts to a number, push to stack.
6. Not a word, not a number, so error (stop interpreting current input).
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
If you really want to do this project, then you need to learn how interpreters work, because that's what you're doing: writing an interpreter for CG functions. Among other things, that means you have to parse and interpret some fairly complex C expressions, which tends to put the complexity of such an interpreter on about the same level as writing a C compiler.

It wouldn't necessarily be that hard, you would need function names, parenthesis, float and int parsing. No grammar would be necessary since there would be no nesting and no precedence, which means the parser could be made quite simple.

There would be no way of validating pointers beyond a check for NULL.

Also no conditionals, no loops and no variables. And on the backend, no code generation or optimization, just a function call when the parser has found the right function.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,739
8,415
A sea of green
It wouldn't necessarily be that hard, you would need function names, parenthesis, float and int parsing. No grammar would be necessary since there would be no nesting and no precedence, which means the parser could be made quite simple.

I was thinking of the supporting data types, like CGPoint, CGRect, and whatnot.

I think it's a good bet you'd need arithmetic operators at a minimum. Unless you're expecting everything to just be numeric literals.

There would be no way of validating pointers beyond a check for NULL.

Also no conditionals, no loops and no variables. And on the backend, no code generation or optimization, just a function call when the parser has found the right function.
Agree on most things. "No variables" seems like a stretch. Who writes real-world CG code that doesn't use variables?

The main purpose of the OP's proposed tool is apparently to select a range of CG code and show its result. Or it's to experiment with writing CG code until something looks right, then paste the resulting CG code into a real C function. I honestly don't see either of those happening without variables of some kind, at least for any non-trivial use.

If the tool is only useful for trivial things, then I question how useful it would be except for beginners. Not that there isn't a market for beginners, I'm just not sure if it's worth doing only for that market. So as often happens, it's not just a technical question, but a business one as well.
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
I was thinking of the supporting data types, like CGPoint, CGRect, and whatnot.

I think it's a good bet you'd need arithmetic operators at a minimum. Unless you're expecting everything to just be numeric literals.


Agree on most things. "No variables" seems like a stretch. Who writes real-world CG code that doesn't use variables?

The main purpose of the OP's proposed tool is apparently to select a range of CG code and show its result. Or it's to experiment with writing CG code until something looks right, then paste the resulting CG code into a real C function. I honestly don't see either of those happening without variables of some kind, at least for any non-trivial use.

Yeah, you would need variables and with them the data types, but you could do without arithmetic operators I think if you just input statements linearly in a textfield. That would be quite limiting though.
 
Last edited:

ytk

macrumors 6502
Jul 8, 2010
252
5
FWIW, there exists a MacRuby library that purports to have wrapped Core Graphics in Ruby. I believe MacRuby already supports most or all of the CG data types natively, and if this library works as exepected it should be very easy to write a program that allows you to input commands as MacRuby statements and draw the results in a view. All of your error handling could be easily done in MacRuby as well, so it should be pretty stable.

The only downside is you'd have to enter your commands as MacRuby statements rather than C/Obj-C statements, but the upside is you'd have to do only a little bit of programming to get it to work. Just create a view and a text field, connect them both to a controller, and have the controller execute the contents of the text field as a MacRuby statement (wrapped around a generic rescue block for simple error handling) when you press return in the field. Done.
 

iSee

macrumors 68040
Oct 25, 2004
3,539
272
This is a pretty interesting topic.

When you think about it, IDEs have been moving closer to automatic and immediate compilation of code... that is, code that is parsed and maybe also compiled as you type.

The auto-completion and highlighters in a some editors seem to at least parse includes, symbols and types, execute the preprocessor, etc. in order to do their jobs.

This seems like a nice extension to that idea: when working with an API whose primary output is visual, why not display that output?

I wonder if on-the-fly compilation and execution might not be the way to go?

E.g., what if it worked like this:

1. text-wise, wrap the input text in a valid function like this (well, this is to give the idea, the real thing would be more complicated and error-free):

Code:
#include (the appropriate headers)

int main()
{
   ... prepare CG rendering environment
   abc();
   ... cleanup
   return 0;
}

void abc()
{
    --paste user's input here--
}

2. compile and link it as appropriate.
3. execute it
4. display the resulting output in the app.

On an error, the app would display it back to the user. Ideally it might even understand the line and character where the error starts and high-light it as the start of the problem area (like a syntax highlighter might).

This would ideally occur continuously as the user types. The most recent successful rendering would remain displayed, so the user would see the rendering update as she/he entered a correct program.

I guess the app would also need to understand parameters and allow them to be entered.

Just thinking "aloud"... Anyway, I like the idea of an interactive CG preview app.
 
Last edited by a moderator:

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,557
6,058
This is a pretty interesting topic.

When you think about it, IDEs have been moving closer to automatic and immediate compilation of code... that is, code that is parsed and maybe also compiled as you type.

The auto-completion and highlighters in a some editors seem to at least parse includes, symbols and types, execute the preprocessor, etc. in order to do their jobs.

This seems like a nice extension to that idea: when working with an API whose primary output is visual, why not display that output?

I wonder if on-the-fly compilation and execution might not be the way to go?

E.g., what if it worked like this:

1. text-wise, wrap the input text in a valid function like this (well, this is to give the idea, the real thing would be more complicated and error-free):

Code:
#include (the appropriate headers)

int main()
{
   ... prepare CG rendering environment
   abc();
   ... cleanup
   return 0;
}

void abc()
{
    --paste user's input here--
}

2. compile and link it as appropriate.
3. execute it
4. display the resulting output in the app.

On an error, the app would display it back to the user. Ideally it might even understand the line and character where the error starts and high-light it as the start of the problem area (like a syntax highlighter might).

This would ideally occur continuously as the user types. The most recent successful rendering would remain displayed, so the user would see the rendering update as she/he entered a correct program.

I guess the app would also need to understand parameters and allow them to be entered.

Just thinking "aloud"... Anyway, I like the idea of an interactive CG preview app.

Since I've also been working on making some Xcode plugins, I did consider the possibility of making the preview window appear right alongside the CG code in Xcode. But it's a lot easier to make a profit from it if I sell it in the Mac App Store, I think, and so I have to have it be a seperate app.
 
Last edited by a moderator:

firewood

macrumors G3
Jul 29, 2003
8,107
1,345
Silicon Valley
There's source code for some C language run-time interpreters (for a subset of C) floating around on the 'net. You might embed a C interpreter inside your compiled Obj C app, and use that to run C code (or just a CG call subset) from your NSStrings.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.