Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jun 13, 2013, 12:35 AM   #1
ArtOfWarfare
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
C Function from NSString?

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!
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 13, 2013, 05:47 AM   #2
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
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!
robbieduncan is offline   0 Reply With Quote
Old Jun 13, 2013, 06:11 AM   #3
gnasher729
macrumors G5
 
gnasher729's Avatar
 
Join Date: Nov 2005
Quote:
Originally Posted by ArtOfWarfare View Post
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.
gnasher729 is online now   0 Reply With Quote
Old Jun 13, 2013, 10:10 AM   #4
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Quote:
Originally Posted by gnasher729 View Post
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.
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 13, 2013, 12:37 PM   #5
cqexbesd
macrumors member
 
Join Date: Jun 2009
Quote:
Originally Posted by ArtOfWarfare View Post
for getting function pointers from NSStrings?
You might be able to use dlsym.

[disclaimer about having only skimmed thread]

Andrew
cqexbesd is offline   0 Reply With Quote
Old Jun 13, 2013, 09:21 PM   #6
chown33
macrumors 603
 
Join Date: Aug 2009
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*
chown33 is offline   0 Reply With Quote
Old Jun 13, 2013, 11:33 PM   #7
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Quote:
Originally Posted by chown33 View Post
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.
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 14, 2013, 12:54 AM   #8
subsonix
macrumors 68040
 
Join Date: Feb 2008
Quote:
Originally Posted by ArtOfWarfare View Post
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.
subsonix is offline   0 Reply With Quote
Old Jun 14, 2013, 01:22 AM   #9
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Quote:
Originally Posted by subsonix View Post
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.
__________________
Don't tell me Macs don't last: 2007 iMac, 2007 Mac Mini, 2008 MacBook Air, all Vintage.
(iMac obsoletion: April 28, 2015, MBA: October 14, 2015, Mac Mini: March 9, 2016)
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 14, 2013, 01:24 AM   #10
subsonix
macrumors 68040
 
Join Date: Feb 2008
Quote:
Originally Posted by ArtOfWarfare View Post
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 by subsonix; Jun 14, 2013 at 01:36 AM.
subsonix is offline   0 Reply With Quote
Old Jun 14, 2013, 02:10 AM   #11
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Quote:
Originally Posted by subsonix View Post
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.
__________________
Don't tell me Macs don't last: 2007 iMac, 2007 Mac Mini, 2008 MacBook Air, all Vintage.
(iMac obsoletion: April 28, 2015, MBA: October 14, 2015, Mac Mini: March 9, 2016)
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 14, 2013, 01:44 PM   #12
bearda
macrumors 6502
 
Join Date: Dec 2005
Location: Germantown, MD
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.
bearda is offline   0 Reply With Quote
Old Jun 14, 2013, 02:36 PM   #13
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by ArtOfWarfare View Post
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).
chown33 is offline   0 Reply With Quote
Old Jun 14, 2013, 02:51 PM   #14
subsonix
macrumors 68040
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
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.
subsonix is offline   0 Reply With Quote
Old Jun 14, 2013, 03:18 PM   #15
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by subsonix View Post
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.

Quote:
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.
chown33 is offline   0 Reply With Quote
Old Jun 14, 2013, 03:31 PM   #16
subsonix
macrumors 68040
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
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 by subsonix; Jun 14, 2013 at 03:38 PM.
subsonix is offline   0 Reply With Quote
Old Jun 14, 2013, 04:05 PM   #17
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
I'm planning on allowing variable declarations and all of the CG functions.
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 14, 2013, 06:45 PM   #18
ytk
macrumors regular
 
Join Date: Jul 2010
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.
ytk is offline   0 Reply With Quote
Old Jun 14, 2013, 09:00 PM   #19
iSee
macrumors 68040
 
iSee's Avatar
 
Join Date: Oct 2004
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.
__________________
"Nobody ever reads these things so I can write anything. I'd eat bananas every day if they were crunchy."

Last edited by OllyW; Jun 16, 2013 at 01:04 PM. Reason: Please use code tags
iSee is offline   0 Reply With Quote
Old Jun 14, 2013, 09:21 PM   #20
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Quote:
Originally Posted by iSee View Post
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 OllyW; Jun 16, 2013 at 01:05 PM. Reason: code tags in quoted post
ArtOfWarfare is offline   0 Reply With Quote
Old Jun 16, 2013, 11:55 AM   #21
firewood
macrumors 603
 
Join Date: Jul 2003
Location: 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.
firewood is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Global function -> normal function? DennisBlah iPhone/iPad Programming 6 Feb 28, 2014 02:40 AM
NSString to NSSize larswik Mac Programming 1 May 28, 2013 07:54 PM
Change numbers in NSString newtoiphonesdk iPhone/iPad Programming 3 Jul 9, 2012 11:33 PM
(NSString*) ?? thedon1 iPhone/iPad Programming 6 Jul 2, 2012 08:52 PM

Forum Jump

All times are GMT -5. The time now is 09:36 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC