I am embedding Lua into a C/C++ application. Is there any way to call a Lua function from C/C++ without executing the entire script first?
I've tried doing this:
//call lua script from C/C++ program
luaL_loadfile(L,"hello.lua");
//call lua function from C/C++ program
lua_getglobal(L,"bar");
lua_call(L,0,0);
But it gives me this:
PANIC: unprotected error in call to Lua API (attempt to call a nil value)
I can only call bar() when I do this:
//call lua script from C/C++ program
luaL_dofile(L,"hello.lua"); //this executes the script once, which I don't like
//call lua function from C/C++ program
lua_getglobal(L,"bar");
lua_call(L,0,0);
But it gives me this:
hello
stackoverflow!!
I am wanting this:
stackoverflow!
This is my lua script:
print("hello");
function bar()
print("stackoverflow!");
end
As was just discussed in #lua on freenode luaL_loadfile simply compiles the file into a callable chunk, at that point none of the code inside the file has run (which includes the function definitions), as such in order to get the definition of bar to execute the chunk must be called (which is what luaL_dofile does).
Found out that the script must be run to call the function.
One possible solution / hack (and please bear in mind that I'm currently unable to test this)...
Insert a dummy "return;" line at the top of your LUA code.
Load your file into a string (like you would in preparation for using luaL_loadstring())
Now it should be a simple matter of using printf_s("return;\r\n%s", [pointer to string holding actual LUA code])
Now you can luaL_loadstring() the concatenated string
The code will still execute, but it should get cut off before it can actually reach anything that does something (in your print("hello"); example, the print line would become unreachable). It should still have updated the list of all the function prototypes and you should now be able to use lua_get() to reference the functions.
NOTE: For those who don't know "\r\n" are the escape codes representing a newline on the Windows OS, and it MUST be those slashes... IE: THIS \r\n NOT THIS /r/n
Related
I've been modifying an example C++ program from the Caffe deep learning library and I noticed this code on line 234 that doesn't appear to be referenced again.
::google::InitGoogleLogging(argv[0]);
The argument provided is a prototxt file which defines the parameters of the deep learning model I'm calling. The thing that is confusing me is where the results from this line go? I know they end up being used in the program because if I make a mistake in the prototxt file then the program will crash. However I'm struggling to see how the data is passed to the class performing the classification tasks.
First of all, argv[0] is not the first argument you pass to your executable, but rather the executable name. So you are passing to ::google::InitGoogleLogging the executable name and not the prototxt file.
'glog' module (google logging) is using this name to decorate the log entries it outputs.
Second, caffe is using google logging (aka 'glog') as its logging module, and hence this module must be initialized once when running caffe. This is why you have this
::google::InitGoogleLogging(argv[0]);
in your code.
I want to extend my application, which is written in C++ using python scripts (extensions). I originally wanted to use TCL for that, just like they do in xchat, for example, but later I decided to use python, because it seems to be quite popular for whatever reasons.
However, I am failing to load and execute even very simple python script. I followed http://docs.python.org/2/extending/embedding.html
When I give a filename of script that I want to load as argument to pName, the error I get from PyErr_Print is: ImportError: Import by filename is not supported.
Reading the documentation, I figured I might need to run PyImport_ExecCodeModule, however this C function requires 2 arguments, 1 is char * (probably a name of module), other one is compiled python code, which according to docs I can get by calling python function compile(). Unfortunately it doesn't say how do I call this python function using C api's in my C++ code. Ideally I would imagine to do something like
PyObject *code = PyCompile("print (\"hello :)\"");
but I couldn't find any function like PyCompile, neither any other C-api function that would simply allowed me to execute python internal function (like compile) and grab its output as PyObject.
So, question is: how can I easily load a python script from a file (something.py) and execute it within my application using the embedded python interpretor?
I have a problem related to passing arguments to a C++ compiled executable. The program emulate the behaviour of a particular inference engine: the setup of the engine is load at runtime from an XML file, and then I want to call it from command line with different input values.
The characteristic of the input are:
Every time that I call the program, the input structure is different, because the system itself is different.
The input is a set of couple {name, value}, one for each part of the system.
I have to separate the configuration XML from the input.
I call the program from a PHP or Node.js server, since it return a result that I expose to the outside through an API.
Input value are obtained from an HTTP post request.
By now I have tried these solutions:
Pass it from the command line ex: "./mysoftware input1 value1 input2 value2 ...etc". A little unconfortable, since I have up to 200 input.
Create a file with all the couples name,value and then call the program that parse the file and then destroy at the end. This is a bottleneck of performance for my API, because at every call I have to create and destruct a file.
Does anyone know a better way to approach this problem?
3. Pass the values to the program via the standard input stream and read them from std::cin inside your C++ program.
I create a simple file, using flex, it generate a file lex.yy.c, for now, I want to put it to C++ program.
%{
#include < stdio.h>
%}
%%
stop printf("Stop command received\n");
start printf("Start command received\n");
%%
When I type start or stop in command line, there is a output. What I want to do is to give the input by my C++ program, and the output of it should be sent to a variable in my program, is it possible? Thanks a lot!
I know the code I post is quite simple, but the result I imagine is:
create c file by flex and bison, and I use it as a header, so in the c++ program, I just need to call a function lex_yacc() to use it. ex. lex_yacc() is a calculator, so I sent an expression with evariables to this function, and it will return the result. I want to use this function in a C++ program, I am confused...Thanks a lot!
See the section about multiple input buffers in the manual. Especially the section about yy_scan_string and yy_scan_bytes.
For the "output", of course the is "output" when you give "stop" or "start" as input, you explicitly do that (i.e. the printf calls). You can put any code you want there.
I am working with Perl embedded in our application. We have installed quite a few C++ functions that are called from within Perl. One of them is a logging function. I would like to add the file name and line number of the Perl file that called this function to the log message.
I know on the Perl side I can use the "caller()" function to get this information, but this function is already used in hundreds of locations, so I would prefer to modify the C++ side, is this information passed to the C++ XSUB functions and if so how would I get at it?
Thanks.
This should work:
char *file;
I32 line;
file = OutCopFILE(PL_curcop);
line = CopLINE(PL_curcop);
Control ops (cops) are one of the two ops OP_NEXTSTATE and op_DBSTATE,
that (loosely speaking) are separate statements.
They hold information important for lexical state and error reporting.
At run time, PL_curcop is set to point to the most recently executed cop,
and thus can be used to determine our current state.
— cop.h
Can't you call perl builtins from XS? I confess I don't know.
If not, you could always do something like this:
sub logger { _real_logger(caller, #_) }
assuming logger is what your function is called (and you rename your C++ XS function to _real_logger. You could also do this, presumably, if you need to hide yourself in the call tree:
sub logger {
unshift #_, caller;
goto &_real_logger;
}
which is of course the normal form of goto used in AUTOLOAD.
These will add overhead, of course, but probably not a big deal for a logging function.