• Advertisement
Sign in to follow this  

Embedding Python/LUA

This topic is 4325 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

OK, ive looked everywhere, or at least, in most places, on a way to embed python in c++. After trying this, i tried LUA, no such luck. All I want to do is enable my C++ application to execute python/LUA scripts. So, I write a function or similar in python/LUA, store that in a seperate file, and in my C++ program, call that file/function, and it runs it with the python/LUA interpreter. This seems to be somethig that many people could benefit from, do you know a way I can do this, or a source that will tell me?

Share this post


Link to post
Share on other sites
Advertisement
Did you try reading the manual?

Both Python and Lua come with manuals, that document how to do exactly that.

There are several libraries that provide additional features on top of the bindings provided by the libraries, too; SWIG is one; boost::python is another (specific to Python); don't know if there's a boost::lua yet.

Embedding LUA in a C++ program is literally a matter of a few lines of code; it's very simple. The manual has good examples.

Share this post


Link to post
Share on other sites
Hmm, decided to go with LUA (had a bit of experience with making a WoW AddOn). After looking through their manual, I can't find any decent examples on how to embed LUA with C++ in it. It has loads of info on syntax, but no info on embedding it.

Share this post


Link to post
Share on other sites
If you're using a newer version of LUA then some of the names have changed and thus old tutorials are kind of rendered moot.

Here's an example I whipped up using the newest version:

lua_State* g_pState = 0;

int main()
{
g_pState = lua_open();
luaL_openlibs(g_pState);
lua_register(g_pState, NameString, FunctionPointer);

luaL_dofile(g_pState, FileNameString);

system("pause");
lua_close(g_pState);
return 0;
}



Everything else is the say as in old the old tutorials (at least as far as I have seen.)

HTH!

Share this post


Link to post
Share on other sites
If you are open to another lua-like scripting language with (closer to) C++ style syntax, and have Visual Studio 2005 (VS8), you can have Squirrel (scripting language) with SqPlus (binding system) compiled and running in about 5 minutes (gcc is also supported with basic makefiles).

Hello World:

int main(int argc,char * argv[]) {
SquirrelVM::Init();
SquirrelObject helloWorld = SquirrelVM::CompileBuffer(_T("print(\"Hello World\");"));
SquirrelVM::RunScript(helloWorld);
SquirrelVM::Shutdown();
return 0;
} // main





Binding a class and interacting between Cpp and script, optional remote debugger usage (forum reformated the listing; see the .zip source file for original formatting):


#ifdef USE_REMOTE_DEBUGGER
void printSQDBGError(HSQUIRRELVM v) {
const SQChar *err;
sq_getlasterror(v);
if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
scprintf(_T("SQDBG error : %s"),err);
}else {
scprintf(_T("SQDBG error"),err);
} // if
sq_poptop(v);
} // printSQDBGError
#endif

static void printFunc(HSQUIRRELVM v,const SQChar * s,...) {
static SQChar temp[2048];
va_list vl;
va_start(vl,s);
scvsprintf( temp,s,vl);
SCPUTS(temp);
va_end(vl);
} // printFunc

// This class will be instantiated and used in script.

class MyClass {
public:
int classVal;
// See examples in testSqPlus2.cpp for passing arguments to the constructor (including variable arguments).
MyClass() : classVal(123) {}
bool process(int iVal,const SQChar * sVal) {
scprintf(_T("classVal: %d, iVal: %d, sVal %s\n"),classVal,iVal,sVal);
classVal += iVal;
return iVal > 1;
} // process
};

int main(int argc,char * argv[]) {
SquirrelVM::Init();
// This example shows how to redirect print output to your own custom
// print function (the default handler prints to stdout).
sq_setprintfunc(SquirrelVM::GetVMPtr(),printFunc);

#ifdef USE_REMOTE_DEBUGGER
HSQREMOTEDBG rdbg = sq_rdbg_init(SquirrelVM::GetVMPtr(),1234,SQTrue);
if(rdbg) {
// Enable debug info generation (for the compiler).
sq_enabledebuginfo(SquirrelVM::GetVMPtr(),SQTrue);
scprintf(_T("Waiting for SQDBG connection..."));
// Suspends the app until the debugger client connects.
if(SQ_SUCCEEDED(sq_rdbg_waitforconnections(rdbg))) {
printf("SQDBG: connected.\n");
} // if
} else {
printSQDBGError(SquirrelVM::GetVMPtr());
return 0;
} // if
#endif

// See examples in testSqPlus2.cpp for script read-only vars, constants,
// enums, static/global functions, variable arguments, constructor arguments,
// passing/returning classes/structs by value or by address, etc.
SQClassDef<MyClass>(_T("MyClass")).
func(&MyClass::process,_T("process")).
var(&MyClass::classVal,_T("classVal"));

SquirrelObject helloSqPlus = SquirrelVM::CompileBuffer(_T(" local myClass = MyClass(); \n local rVal = myClass.process(1,\"MyClass1\"); \n print(\"Returned: \"+(rVal ? \"true\" : \"false\")); \n rVal = myClass.process(2,\"MyClass2\"); \n print(\"Returned: \"+(rVal ? \"true\" : \"false\")); \n print(\"classVal: \"+myClass.classVal); \n "));

try {
SquirrelVM::RunScript(helloSqPlus);
} catch (SquirrelError & e) {
scprintf(_T("Error: %s, %s\n"),e.desc,_T("Squirrel::helloSqPlus"));
} // catch

#ifdef USE_REMOTE_DEBUGGER
if (rdbg) {
sq_rdbg_shutdown(rdbg);
} // if
#endif

SquirrelVM::Shutdown();
return 0;
} // main





The remote debugger is portable and uses the Eclipse environment (supports syntax highlighting, etc.).

You may also want to check out Angel Script (a statically-typed scripting language (lua and Squirrel are dynamically typed)).

Share this post


Link to post
Share on other sites
If you really have your heart set on LUA/Python and free forms of data are not helping, I would try "Game Scripting Mastery". Its a *very* good book on scripting extensions and embedding. It will deviate about half way through where you design your own system, both IL and HL - but the first part of it has about the best demonstration for extending/embedding for TCL, Python, and LUA.

You should be able to get a used copy for a reasonable price.


I hope that helps.

Share this post


Link to post
Share on other sites
Thanks everyone for your help.

Barakus,

I tried that tutorial, doesnt seem to work with LUA 5

Benstr,

Thanks for the links! Programming in LUA seems good, but complex. LUAPlus doesnt provide enough information on embedding it, so i think I'll give it a miss.

Programmer16,

Yes, I think the problem is that LUA no longer supports those functions, so thanks for the new code. But I think you've used variables instead of actual arguments. What do these variables represent, do you recon you could walk me through it?

John Schultz,

Thanks, but I'm not using VC++, I'm using Code::Blocks (with Dev-cpp's compiler). I did look at squirrel beforehand, but decided against it (but Ive forgotten why, so Im looking at it again. SqPlus looks good too (just found out that you made it) Ill look into that.

Xiuhcoatl,

That would sort of be a last resort. Im in the middle of SAMS Teach Yourself C++ in 21 days, and am waiting for Code Complete, so Im kind of short on book reading time. Im positive that I can get something to work, but such a purchase may be nessessary in the near future. Thanks for the pointer!

Share this post


Link to post
Share on other sites
Quote:
Original post by Silvo
Thanks, but I'm not using VC++, I'm using Code::Blocks (with Dev-cpp's compiler). I did look at squirrel beforehand, but decided against it (but Ive forgotten why, so Im looking at it again. SqPlus looks good too (just found out that you made it) Ill look into that.


It looks like Dev-cpp can use gcc; Squrriel with SqPlus should work OK (tested).

Share this post


Link to post
Share on other sites
Quote:
Original post by Silvo
Programmer16,

Yes, I think the problem is that LUA no longer supports those functions, so thanks for the new code. But I think you've used variables instead of actual arguments. What do these variables represent, do you recon you could walk me through it?



lua_register(g_pState, FunctionName, FunctionPointer);

// Example
int sfSpeak(lua_State* pState)
{
// This returns the number of arguments that the user supplied.
lua_gettop(pState);

std::cout<<lua_tostring(pState, 1)<<": "<<lua_tostring(pState, 2)<<std::endl;
return 0;
}

lua_register(g_pState, "UserSpeak", sfSpeak);
// The FunctionName argument is the function name that will be used
// inside of the script.

/*
Talking.lua
-----------
UserSpeak("Donny", "This is a user speaking.");
UserSpeak("Silvo", "This is another user speaking.");
*/


// lua_dofile just a pointer to your virtual machine and a script filename.


I just started learning myself, so some of what I may be doing is wrong. For instance, in sfSpeak you should check to make sure that lua_gettop() returns 2 (meaning that the function was called with 2 strings.)

HTH!

Edit: Check out the tutorials at tonyandpaige.com. They're the ones that I used to get started (they use the old version, but other than the luaL_XXX functions that were in my first snippet, everything else seems to be the same.

Heres a link: TonyAndPaige.com

Share this post


Link to post
Share on other sites
Programmer16,

I wish I understood what it all means... I used the tutorial you linked to, replacing your function names with theirs, but im getting some linker errors.

"
mian.cpp:13: error: `luaL_newstate' undeclared (first use this function)
mian.cpp:13: error: (Each undeclared identifier is reported only once for each function it appears in.)
mian.cpp:17: error: `luaL_dofile' undeclared (first use this function)
"

yes, i spelt 'main' wrong... oh well. Also, it cant find luaxlib.h, but it's there

John,

Can you direct me to a hello world tutorial for squirrel and SqPlus?

Share this post


Link to post
Share on other sites
Quote:
Original post by Silvo
Can you direct me to a hello world tutorial for squirrel and SqPlus?


Download and unzip the SqSplus .zip.

1. Go to the top level directory to where you unzipped the files and type: make sq32 (or examine the Makefiles and recreate in your IDE).
2. Go to the minimalSqPlus directory and type: make
3. type: ./minimalSqPlus to run.
4. See minimalSqPlus.cpp for more info.
5. See testSqPlus2/testSqPlus2.cpp for examples of just about everything you might need for binding. See the Squirrel forum for more info (other gcc/non-VC users are helpful).

Squirrel Docs
Squirrel Forum

Share this post


Link to post
Share on other sites
Thanks for the assisstance.

Just to let you know, im using Windoze, so the make stuff and ./blah dont work. I tried looking at the Makefiles (not sure what these do), and saw some stuff under sq32, so I added them as link libraries. The problem is that these dont exist, so after removing them from the list, it cant find any of the functions (copied the source from minimalSqPlus.cpp). Im assumming i need some libraries, but i cant see them. (looked in the lib folder).

Share this post


Link to post
Share on other sites
Quote:
Original post by Programmer16
If you're using a newer version of LUA then some of the names have changed and thus old tutorials are kind of rendered moot.

Here's an example I whipped up using the newest version:
*** Source Snippet Removed ***

Everything else is the say as in old the old tutorials (at least as far as I have seen.)

HTH!


Is that using C++ or C? On my Mac I can get Lua to work fine with a C app compiled with gcc, but when I use a C++ app compiled with g++ I get an error that lua_dofile is undeclared. I'm using extern "C" {} for the lua headers and I'm positive I'm linking to the libraries properly (again, I can get it to work using straight C). Any ideas how to get it to work in C++? Here's my full code:

#include <stdio.h>
#include <stdlib.h>

extern "C" {
#include <lua.h>
#include <lualib.h>
}

lua_State *L;

int main(int argc, char * const argv[])
{
L = lua_open();
luaopen_base(L);
lua_dofile(L, "SimAI.lua");
lua_close(L);
return 0;
}

Share this post


Link to post
Share on other sites
Figured out the problem. I do need to include <luaxlib.h> but when it installed it, it created it as lauxlib (the u and a are backwards). After renaming that and using luaL_loadfile() it works just fine.

Share this post


Link to post
Share on other sites
Quote:
Original post by Silvo
Thanks for the assisstance.

Just to let you know, im using Windoze, so the make stuff and ./blah dont work. I tried looking at the Makefiles (not sure what these do), and saw some stuff under sq32, so I added them as link libraries. The problem is that these dont exist, so after removing them from the list, it cant find any of the functions (copied the source from minimalSqPlus.cpp). Im assumming i need some libraries, but i cant see them. (looked in the lib folder).


Silvo, is there some reason you can't use the free version of Visual Studio 2005 (C++ Express)?

It sounds like the trouble you are having with embedding a scripting language is due to the compiler/IDE/environment you are using as opposed to the scripting language and binding tools.

If you download the free VS2005 for C++, you will be able to open the Squirrel/SqPlus solution (.sln file) and immediately compile, link and run with no problems. If you need to use some other IDE/compiler, you can study the VS2005 solution items and recreate the build/make files from scratch.

Share this post


Link to post
Share on other sites
Nick Gravelyn,

Just checked, I have that same problem. luaxlib.h was called lauxlib.h. Are their any libraries I need to include, or are the headers all that i need?

John,

I did have a copy of VC++ Express 2005 (still got it on a CD somewhere), but I found it very... clunky. Also, getting SDL to work was impossible, so I changed to Code::Blocks, and havent had any problems (till this). Unfortunatly, I have since uninstalled VC++, but may have to install it again, just to test if SqPlus will work with it. If is does, I'll have to find if it's easier to get SqPlus to work with Code::Blocks, or SDL with VC++. Also, how would I use these Makefiles with Code::Blocks (or dev-cpps compiler, I think it's gcc)??

Thanks for all your help.

Share this post


Link to post
Share on other sites
Quote:
Original post by Silvo
I did have a copy of VC++ Express 2005 (still got it on a CD somewhere), but I found it very... clunky. Also, getting SDL to work was impossible, so I changed to Code::Blocks, and havent had any problems (till this). Unfortunatly, I have since uninstalled VC++, but may have to install it again, just to test if SqPlus will work with it. If is does, I'll have to find if it's easier to get SqPlus to work with Code::Blocks, or SDL with VC++. Also, how would I use these Makefiles with Code::Blocks (or dev-cpps compiler, I think it's gcc)??


Silvo, do you know how to create a project from scratch using Code::Blocks? If so, you can create a new project, then add the files in each directory for Squirrel/SqPlus. You can figure out which files are needed by looking at the Makefiles in a text editor (you also need to determine which Makefiles are creating libraries, and which are creating executables). When you see *.cpp in a makefile, that means all the .cpp files in that directory, etc. You can find the docs for GNUMake here. While GNUMake is reasonably powerful, it's not well suited for beginners (though not too bad for simple projects).

It will probably take you less time to re-install VC2005 and immediately compile and run SqPlus than it will to figure out how to read Makefiles and create new projects in Code::Blocks. After re-installing VC2005, you might try Visual Assist X (VAX). VC2005+VAX rocks. After trying VC2005 (and perhaps VAX), I'd be curious to hear your analysis as to why you prefer another IDE.

BTW, if you install Cygwin, you can use the Makefiles and the gcc compiler from the command line (as noted in a previous post. Cygwin is a *nix style environment; you use ./exename etc.). Your best bet to quickly get something running is with VC2005 and SqPlus (will compile and run with no errors, no warnings, etc.). Once you are confident the scripting language is solid/what-you-want, you can figure out how to recreate the projects/makefiles with Code::Blocks, etc. However, the VC2005 compiler and debugger are the best in the business (fastest code (general case), now very standards compliant etc., compiles faster than gcc (while producing faster code (sometimes much faster, etc.)), using VAX for the first time will blow your mind (very cool/powerful: even spell checks your code; no longer waste time recompiling due to typos)).

Share this post


Link to post
Share on other sites
Wow! you really like VC++. Alot. I found that it was quite clunky, oh well. I managed to get GameMonkey script to work. Just remembered about having to add .cpp files directly to the project, so that worked. Now im back to tampering with Code::Blocks, Squirrel and SqPlus, i think the reason it can't find the definitions is that they haven't been included correctly (not just #include, but I need to manually add each .cpp file that is being used). Hopefully this should make it work.

Thanks again for all your help.

EDIT: Visual Assist X looks really good. I think I'm going to have to re-install VC++ just to check it out.

Share this post


Link to post
Share on other sites
I DID IT!!!!!

I have to add all these squirrel and SqPlus related files, and then not add these ones, but these ones i do... But I managed to get the minimal example to compile and run! Using Code::Blocks!!!

I'm happy!

Thanks for all the help, now I've gotta learn how to use it. Another adventure...

Share this post


Link to post
Share on other sites
Quote:
Original post by Silvo
I DID IT!!!!!

I have to add all these squirrel and SqPlus related files, and then not add these ones, but these ones i do... But I managed to get the minimal example to compile and run! Using Code::Blocks!!!


Cool!

Re VC++ (IDEs): VC6 was fast and clean, VC7.1 was a little slower, but more features, VC8 is even slower (perhaps that's what you mean by clunkier), but provides a better overall interface (who knows, maybe they'll speed/clean it up by version 8.1+). As for generated code, the new profile-guided optimization is pretty cool (VS2005 Pro; not sure if comes with Standard or Express).

Re VAX: It's an amazing product. Alt-O to switch between .h/.cpp, open a file in the workspace with just a few letters of the file name, find any symbol by typing a few letters, spell/validation of all variables/functions (no more typos before compile), auto-complete variables, functions, members (way less typing), faster key repeat (download the demo for more info). It's the best development enhancement tool I've seen in a long time. For really large projects, IncrediBuild is also very useful (multiple parallel builds on many machines in your office (can get expensive, but for large commercial projects, definitely worth it)). These add-in products only work with VC. Additionally, after you reinstall VS2005, compare build times when rebuilding your entire project (compared to an IDE using a gcc compiler); also compare runtime speed (optimized builds).

Now that you have GameMonkey and Squirrel/SqPlus working, you might want to also try out Lua, Python, and AngelScript. Perhaps post what you like/dislike about each language/binding system.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement