Embed Python HTTP server into C program as RPC server? - c++

I have a program written in C++ with a web interface to for the purpose of RPC. I can call http://localhost/ListVariables or http://localhost/RunFunction?var=1 and have the C code execute ListVariables or RunFunction. It works, but I'd rather not have to manage the web server in C/C++ when there are so many good Python web servers out there.
What I'm imagining is having the C program call into Python to start a web server on another thread (i.e. Tornado), return to C and then continue chugging along doing calculations. Then when the Python server receives a request on http://localhost/ListVariables, it calls back into C and executes ListVariables on the already running process.
C -----> processing -----------> processing ------------> RPC: FuncA -------->
| ^ |
\---> Python Web Server ---------- Request for: FuncA --/ ... \-------->
^
browser: http://localhost/FuncA ---/
The project has the unfortunate caveat that the program must be started from C to begin with. After doing some research this seems to be a bit of a border case, since Python-->C and C-->Python can be done with Cython. However, I can't find many resources on C-->Python-->C, as most of the examples I've found describe linking to libraries and not to already-running processes. Is it possible to have Python call back into a running C program?

Absolutely. Create a "fake" module in the C program injected into sys.modules that the Python code can import and access as it would any other module.

I personally really like the boost::python library for embedded python into c++ and dealing with data binding and callbacks between the two. http://www.boost.org/doc/libs/1_51_0/libs/python/doc/
That being said, what you're proposing sounds like a bit of a PITA. I've personally have had a lot of success using http://libevent.org/ to fulfill my embedded webserver needs. It handles all of the http server stuff for you, all you need to do is give it the urls you want to handle and a callback, put the event_base_loop somewhere in your main loop (or in it's own thread if you'd rather), and away you go. That to me seems like it might be a lot easier than embedding python and dealing with passing data and data structures between the two.

Related

Is there a way to send C/C++ commands using Johnny-Five?

Currently running a number of ESP8266s flashed with StandardFirmataWiFi using a central linux machine running J5. So instead setting up a bunch of micro-controllers to run autonomously, they are all WiFi enabled and under the command of a single machine.
So far this has been working very well. I'm very familiar with JS, not super familiar with C/C+
But occasionally I find example code in C/C+ for which I can't find a J5 equivalent.
Question:
Is it possible to issue C/C+ (or even Python) commands from Johnny-Five? So in other words instead of the central machine issuing J5-only commands to the micro-controllers, is there way to have J5 send C/C+ snippets? If so, that would make it easier to work directly with demo/community-shared code while also making it easier for JS-fluent developers to transition toward C.
C and C++ are compiled languages. That means you need a compiler in order to translate C or C++ code into something that can be run on a processor. Because of that there's no eval() in C or C++, no function which can text a chunk of text and process it as C or C++ code.
So there cannot be a way for Johnny-Five or anything else to send C or C++ code to an ESP8266 - the ESP8266 is not capable of running a C or C++ compiler and cannot translate C code into something it can execute. You could potentially transfer compiled ESP8266 code but there are so many difficulties with that approach that you shouldn't waste time considering it.
Like Javascript, Python is an interpreted language. It has an eval() function that you can execute a string as Python code. If you can arrange to have a handler on the ESP8266 receive a string and then eval it, you could send Python commands from a remote program.
Beware that there are huge gaping security issues with doing something like that - you're literally allowing a remote program to execute whatever it feels like on the ESP8266.

Ways to communicate between JScript and Windows service

I have a Windows local service that may spawn off a process to execute a JScript script (in a .js file) via the Windows Script Host. The issue is that I need to notify my service of the results generated by the script in the .js file. A transfer or a simple 32-bit integer, or a string would suffice. What would be the way to do this?
PS. The code must run on Windows XP SP3 or later OS.
Your best bet is to create an out of process COM object that executes within your service. Just implement the necessary scripting interfaces and provide a member function to match the notification and call it from your script as such:
newObj = new ActiveXObject("localserver.mynotify");
newObj.Notify("finished");
Would the exit code of the process be enough?
Windows Scripting host has has a .Quit(errorCode) method that allows you to set the exit code.
You should be able to call WSH directly from the service and get the return code with GetProcessExitCode() by passing the process handle that you received after spawning it.
Note that almost everything you can do from a JScript file can also be done with native code.
Do you have to execute the .js file as an external process? Windows Scripting has COM objects that an app can use to run scripts within its own process. I use this to execute script files within my service processes, and it works fine. The hosting process can even implement its own IDispatch-based classes and pass them to the scripting engine to expose to scripts as global objects so the scripts can communicate with the hosting process without having to use new ActiveXObject or CreateObject() to access those objects.
I see your script is written in JScript and your app in C++.
Perhaps the easiest way to accomplish what you want is by writing a file, say, to programdata folder which your service should have access to. Maybe use a GUID for the particular request, pass that to the JScript so it's guaranteed to be a unique file. Not ideal.
Another way to get JScript output ... Can you call out to managed code (C#)? If so, you could use a .NET-based or .NET-callable JavaScript compiler/interpreter. This would allow you to avoid IActiveScript and also to grab the values right out of the script context or from function return. I've used Jurassic and JavaScriptDotNet, both very easy to use and extend.
This might open a problem if you heavily rely on ActiveXObject calls (ie: FileSystemObject) and don't want to write components. JuraScript wraps the Jurassic engine and add ActiveXObject support to it for COM automation.
I am a C++ newb, so I don't know how much of a leap this is for you although I know it's possible to interop between managed/C++.
Just thought I'd mention these scenarios as I didn't see them listed in answers.

How to use c++ module with yaws

I don't have experience in using c++ with apache or other web server. But now want to use it with yaws to generate pdf from passed data. May be somebody has experience in doing so. Please any link. I havent found any. May be better to not use executable file but library and call its functions from yaws module.
Since you included the cgi tag on your question, one way to do this is to use the Yaws CGI capabilities. You'd simply run your C++ program as a CGI program. Yaws also supports FCGI, which lets you avoid starting a new instance of your C++ program for every request and instead have a dedicated TCP connection between Yaws and a daemon instance of your program.
Another way to do this is to write a Yaws appmod exporting an out/1 function. The argument to this will be an #arg record detailing all the information of the request being served. Your out/1 function could then call into an Erlang NIF written in C++, passing whatever information from the request it needs, and then taking replies and giving them back to Yaws as responses. PDF data could be returned from your NIF as Erlang binaries. With this approach, your C++ code runs in the same OS process as Yaws, so you have to be careful that your code never crashes else it will take the whole Erlang VM down with it, but aside from that this approach would be more efficient than FCGI or CGI.

Connect c++ application with an http calls?

is it possible to get the output of an c++ project as http request
eg:http://localhost:8080
just it need to output an xml or just any output...
Yes - this is typically some sort of CGI mechanism. Depending on the software you're using to run your webserver, if it supports CGI, it can be configured to invoke your program when certain URLs are requested. Your program's output to stdout would then be sent back to the HTTP client.
Be careful with this approach, especially if your application takes input from the user: bugs in your program can lead to security vulnerabilities if, for example, you have the possibility of a buffer overflow. Interpreted languages can sometimes offer some protection here.
You can use any executable as a CGI script (though they are usually perl or shell scripts).
Make your c++ executable print whatever you need to stdout (cout).
Here is a great into to CGI, and 4.2 tells you that you can make any executable run via CGI.

Embedding a Ruby interpreter in a C++ app

I'm hoping to use Ruby as a scripting language for my game engine. I've found the usual articles describing how to call Ruby classes from C++ code and vice versa (e.g. here) but I can't quite see how to do what I want with that way of working...
My engine currently uses a little language I wrote myself with Flex and Bison, and a little stack based virtual machine. Scripts don't always run right through from start to finish, for instance they sometimes includes commands like "sleep for 2 seconds" or "wait until character has finished walking", so the scheduler keeps tabs on the status of each script and an instruction pointer, and knows when to resume them, and so on.
So it seems that I really need some kind of embedded Ruby interpreter that I can exercise a certain degree of control over, rather than simply calling Ruby methods. Or am I just being obtuse and missing something?
I'm working in Microsoft Visual C++, so ideally any solution would compile nice and easily in that.
Here's an example including error handling.
#include <iostream>
#include <ruby.h>
using namespace std;
int main(void)
{
ruby_init();
ruby_init_loadpath();
int status;
rb_load_protect(rb_str_new2("./test.rb"), 0, &status);
if (status) {
VALUE rbError = rb_funcall(rb_gv_get("$!"), rb_intern("message"), 0);
cerr << StringValuePtr(rbError) << endl;
};
ruby_finalize();
return status;
}
You're on the right track. The key is to do something similar to the section on Embedding Concepts in the link you posted. In simple terms it's little more than:
ruby_init();
ruby_script("some_script");
You may need to copy over all the #ifdef stuff from main.c to get everything working. From then it's a matter of building an API to your C++ functions you want to expose, and depending on your design, multi-threading the thing.
You could always re-design the way the scripts work to suit the script engine rather than trying to get the engine to work with the original scripting paradigms.
So, if you had this:
proc:
action 1
action 2
sleep a bit
action 3
end
which would require the script to be suspended on the sleep line, do this:
proc
action1
action2
set timer (time, callback_proc)
end
callback_proc
action3
end
which lets the scripting engine finish each method neatly. It wouldn't need many changes to the hosting side - each version requires some form of event system which can restart the script engine.
There is a guide about how to embed ruby into a C++ application. That may be helpful. Otherwise go to the Ruby documentation.
The Embed Ruby in C article may be helpful, too.
I think what your going to want to do is use Ruby's threads. I've done a fair bit of digging through the Ruby threading code and I know that (where pthreads is available) sleep is implemented in a non-blocking fashion using pthread_cond_timedwait. This unblocks the interpreter so that other threads can continue execution.
Your own code is going to have to respect Ruby's threads when it comes to interacting with the Ruby interpreter. They've still got a Global VM Lock in Ruby which means you should be careful about modifying anything in the interpreter without having the lock yourself.