问题
I want to take a string in ObjC and evaluate it as if it were code. For example (these are made-up functions):
NSString *Cmd=@" if (10>5) NSLog(@"Test"); ";
MyClass.Run(Cmd);
I expect that "Test" appears in the output log. I have searched and tested a lot of code samples and library but still no good results.
I Ended Up with these 2 libraries for compilation at runtime:
1- libClang framework and clang_Cursor_Evaluate function .
https://www.mikeash.com/pyblog/friday-qa-2014-01-24-introduction-to-libclang.html
https://github.com/root-project/cling
2- objc-eval framework .
https://github.com/antipax/objc-eval/blob/master/README.mdown
I could not do anything with libClang. and left as it is for now, but with the second one, I successfully compiled the framework and actually used it in a simple project, however still no proper output!
#import <Foundation/Foundation.h>
#import "OEEvaluation.h"
void main()
{
Code1:OEEvaluation *evaluation = [OEEvaluation evaluationWithCode:@"retun @\"Hello World!\" ;" delegate:nil];
Code2://OEEvaluation *evaluation = [OEEvaluation evaluationWithCode:@"NSLog(@\"Hello World!\");" delegate:nil];
NSLog([evaluation evaluateSynchronously]);
NSLog(@"Test");
}
No output with Code1 and Code 2: no (null), no error, no hint.. nothing at all.
Code 1 is the exact sample from the framework's documentation.
Maybe I am wrong but I think the solutions I found are the closest ones to the answer between my researches.
Now the questions are:
1- How can I accomplish this idea (convert a string into an executable line of executable code)?
2- How can I get the objc-eval.framework to work?
回答1:
How can I get the objc-eval.framework to work?
The full source is available, work your way through it.
You will discover that it runs your code by splicing it into an Xcode project that it creates by unpacking a tar
archive, calling xcodebuild
to compile that project, and then dynamically loading the compiled code and executing it.
Your first problem is that the tar'ed archive is rather old and needs updating for the latest version of Xcode – Xcode provides the option to do this. Having done that the project will compile but you'll find the compiled code is not where this framework expects to find it – this is because by default the project settings which set the location of the products are overridden in the latest versions of Xcode.
You need to explore Xcode's Preferences…
, the project's Build Locations
settings, the arguments the xcodebuild
command takes, and the code in the framework which loads the compiled binary to decide which settings will get the compiled binary where you want it so the framework can access it.
Once you do that you'll find the framework works. Note that for this to work at all requires Xcode to be installed on any system your app runs on.
Have fun!
HTH
来源:https://stackoverflow.com/questions/46904904/convert-compile-a-string-into-executable-code-in-objective-c