Python object for C ++ inline pointer
I love the idea of ββusing python as an embedded scripting language for a project I'm working on and you have everything working. However, I can't seem to convert the python extended object back to native C ++ pointer.
So this is my class:
class CGEGameModeBase
{
public:
virtual void FunctionCall()=0;
virtual const char* StringReturn()=0;
};
class CGEPYGameMode : public CGEGameModeBase, public boost::python::wrapper<CGEPYGameMode>
{
public:
virtual void FunctionCall()
{
if (override f = this->get_override("FunctionCall"))
f();
}
virtual const char* StringReturn()
{
if (override f = this->get_override("StringReturn"))
return f();
return "FAILED TO CALL";
}
};
Accelerated packaging:
BOOST_PYTHON_MODULE(GEGameMode)
{
class_<CGEGameModeBase, boost::noncopyable>("CGEGameModeBase", no_init);
class_<CGEPYGameMode, bases<CGEGameModeBase> >("CGEPYGameMode", no_init)
.def("FunctionCall", &CGEPYGameMode::FunctionCall)
.def("StringReturn", &CGEPYGameMode::StringReturn);
}
and python code:
import GEGameMode
def Ident():
return "Alpha"
def NewGamePlay():
return "NewAlpha"
def NewAlpha():
import GEGameMode
import GEUtil
class Alpha(GEGameMode.CGEPYGameMode):
def __init__(self):
print "Made new Alpha!"
def FunctionCall(self):
GEUtil.Msg("This is function test Alpha!")
def StringReturn(self):
return "This is return test Alpha!"
return Alpha()
Now I can call the former for functions fine by doing this:
const char* ident = extract< const char* >( GetLocalDict()["Ident"]() );
const char* newgameplay = extract< const char* >( GetLocalDict()["NewGamePlay"]() );
printf("Loading Script: %s\n", ident);
CGEPYGameMode* m_pGameMode = extract< CGEPYGameMode* >( GetLocalDict()[newgameplay]() );
However, when I try to convert the Alpha class back to its base class (last line above), I get a promotion error:
TypeError: No registered converter was able to extract a C++ pointer to type class CGEPYGameMode from this Python object of type Alpha
I've done a lot of searching the net, but can't figure out how to convert the Alpha object to a pointer to its base class. I could leave it as an object, but rather have it as a pointer to use its non-python code. Any ideas?
source to share
Thanks to Stefan from python c ++ mailling list I was missing
super(Alpha, self).__init__()
from a constructor call meaning it never did the parent class. Thought it would be automatic: D
The only other problem I had was to keep the new instance of the class as a global var, otherwise it got cleaned up as it went out of scope.
So happy now
source to share
Well, I'm not sure if this will help you, but I had the same problem with scripting in Lua. We created objects from Lua and wanted the C ++ code to handle objects using pointers. We did the following:
- all object objects were written in C ++, including constructors, destructors and factory method;
- The lua code called the factory method to create an object. this factory method 1) gave the object a unique identification number and 2) registered it in the C ++ map which mapped the identification numbers to its own pointers;
- so, whenever lua was about to pass a pointer to C ++ code, it gave the object ID instead, and the C ++ code looked for a map to find the actual pointer by ID.
source to share
There may not be the answer you are looking for, but take a look at ChaiScript for embedding in your C ++ application.
According to their website,
ChaiScript is the first and only scripting language developed from being based on C ++ compatibility in mind. It is inspired by ECMAScript, a built-in function-like language.
ChaiScript has no meta-compiler, no library dependencies, no build system requirements, and no legacy baggage either. At can work seamlessly with whatever C ++ functions you show them. It doesn't need to be explicitly stated about any type, it's function oriented.
With ChaiScript you can literally start writing your application by adding three lines of code to your program and not changing your build steps at all.
source to share