Python object to C++ pointer problem - c++

this is my first post :). I could convert a python extended object into a C++ pointer, but I have a problem. First I will show you my code and then I will explain the problem.
This is my class:
#include <boost/python.hpp>
using namespace boost::python;
class Base
{
public:
virtual const char* HelloWorld() = 0;
};
class BaseWrapper : public Base, public wrapper<BaseWrapper>
{
public:
virtual const char* HelloWorld()
{
if (override f = this->get_override("HelloWorld"))
return call<const char*>(f.ptr());
return "FAILED TO CALL";
}
};
Boost wrapping:
BOOST_PYTHON_MODULE(hello_ext)
{
class_<Base, boost::noncopyable>("Base", no_init);
class_<BaseWrapper, bases<Base> >("BaseWrapper")
.def("HelloWorld", &BaseWrapper::HelloWorld);
}
The Python code (hello.py):
def NewDerived():
import hello_ext
class Derived(hello_ext.BaseWrapper):
def __init__(self):
super(Derived, self).__init__()
def HelloWorld(self):
return "This is a Hello World!!!"
return Derived()
and the main file:
int main()
{
// Start the interpreter.
Py_Initialize();
// Import the module that we need (hello.py)
object module = import("hello");
// Get a C++ pointer of the derived python class.
Base* base = extract< Base* >( module.attr("NewDerived")() );
// Call the HelloWorld function
std::cout << base->HelloWorld() << std::endl;
}
When I run my application I can see at the screen "This is a Hello World!!!" as I expected.
So, what is the problem??? Suppose I change the python code to:
def NewDerived():
import hello_ext
class Derived(hello_ext.BaseWrapper):
def __init__(self):
super(Derived, self).__init__()
def HelloWorld(self):
return "This is a Hello" # I CHANGED THIS LINE!!!!
return Derived()
Then, when I run my application again, it crashes, because I got an error in the line:
std::cout << base->HelloWorld() << std::endl;
because base is NULL.
More precisely, the error is "Access violation reading location 0xblablabla".
When I debug, the debugguer stops at the function (Boost or Python code, I think)
inline api::object_base::~object_base()
{
Py_DECREF(m_ptr);
}
What do you think???

Finally, another programmer explained me the solution.
I don't know why it worked originally, but the problem is that the object is getting destroyed before I try calling the member function. I need to break the extract call into two parts like so:
object derived = module.attr("NewDerived")();
Base* base = extract< Base* >( derived );
This will keep the object around long enough for me to actually call functions on it.

Related

boost-python pure virtual detecting missing implementation

I have a C++ class with a pure virtual method exposed to python using boost-python. I am calling the virtual function from C++ and assuming the virtual function is implemented in python. It all works if the function is implemented but if it's not I get a nasty exception.
I am trying to find a way to detect if the method is in fact implemented without calling when I load the class
Roughly the code looks like this
#include <boost/python.hpp>
using namespace boost::python;
public Foo {
public:
void func() = 0;
}
class PyFoo : public Foo, public boost::python::wrapper<Foo> {
public:
void func() override {
get_override("func")();
}
};
BOOST_PYTHON_MODULE(example)
{
using namespace boost::python;
class_<PyFoo>, boost::noncopyable>("Foo")
.def("func", pure_virtual(&PyFoo::func))
;
}
void create {
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
std::string overrideCommand(
R"(
import example
class MyFoo(example.Foo):
def __init__(self):
example.Foo.__init__(self)
# virtual function in C++. (Should be defined)
# def func(self):
# print('func called')
)");
boost::python::exec(overrideCommand.c_str(), main_namespace);
result = eval("MyFoo()", main_namespace);
// Can I detect if 'result' has func implemented? If I call it and it
// is not defined death results. I have tried:
object attr = result.attr("func");
// but attr always seems to be set even if there is no function,
// I think from the base class Foo.
// This is the call:
Foo& t = extract<Foo&>(result);
t.func();
}
You can use PyCallable_Check.
if (!PyCallable_Check(result.func()))
{
PyErr_SetString(PyExc_TypeError, error_msg.str().c_str());
python::throw_error_already_set();
}
I found a solution. Workable not elegant. I added the method:
bool isThere() {
auto obj = get_override("func");
return PyCallable_Check(obj.ptr());
}
to FooPy. Then:
FooPy& t = extract<FooPy&>(result);
t.isThere();

Loading derived class from DLL does not contain derived attributes

i am working with DLLs and i am new to it.
I am trying to load derived class inherited from my Interface
class IModule{
public:
virtual ~IModule(); // <= important!
vector<String> getFunctions();
protected:
vector<String> mFunctions;
};
class DllModule : public IModule {
public:
DllModule() {
this->mFunctions.push_back("Algorythm");
};
private:
int test;
};
and here I want send pointer to my application
extern "C" {
IModule* CreateModule() {
// call the constructor of the actual implementation
IModule * module = new DllModule;
// return the created function
return module;
}
}
In my application after I load it
f_GetFunctions funci = (f_GetFunctions)GetProcAddress(hGetProcIDDLL, "CreateModule");
if (!funci) {
std::cout << "Could not locate function CreateModule" << std::endl;
//return EXIT_FAILURE;
return nullptr;
}
IModule* module = funci();
I expect the mFunction populated, but its like new instance of IModule instead of DllModule loaded from DLL. All I want is loop at mFunctions and populate my combobox in QT_App.
Can somebody help me? What's wrong with my expectations?
Thank you very much.
(Everything is done in Windows10)
Edit1: Changed types to minimal (sorry for that)
Function => String
Edit2: I completly forgot about assigning pointer
I was able to circumvent my problem.
I used QLibrary.Load() instead of LoadLibraryA and it did exactly what i wanted.

Why can I call instance functions statically?

I was looking around the Notepad++ source code on GitHub recently, and came across a method call like this:
Window::init(hInst, parent);
I searched for the function it was referencing to, and came across a Window class- but the init function was marked virtual, so clearly it was non-static. Thinking I made a mistake, I checked the entire header to make sure there was no static overload of init, and I made sure there was no Window.cpp file. There isn't.
After poking around the source for 15 more minutes, I gave in and git cloned the repo locally so I could open it in Visual Studio. The first thing I did was to build just to make sure this wasn't an accidental merge on behalf of the project developers- the build succeeded.
The next steps I took:
I opened the the file calling Window::init and clicked Go To Declaration on Window. It takes me to the Window class.
I clicked Go To Declaration on the init function. It points me to the signature of the virtual method.
I copy and paste the Window.h file into an entirely new header and replace all references of Window with Foo. When I type in Foo::init, the compiler complains that 'a nonstatic member reference must be relative to a specific object'.
TL;DR: Somehow, the Notepad++ source code calls a non-static method statically, and this builds. Doesn't work with any other class. Proof here and here.
I have spent 2 hours staring at this, but I still don't see how it's possible. Am I missing something?
No, it's not calling a static function. It's just calling the base class's version of init(). Basically, in tClassName::f, you are asking "I want to call that specific version of the virtual function f() in class tClassName".
Generally, it's pretty common to call the base class's counterpart of a virtual function in the derived class. E.g., the factory method pattern:
#include "tObject.h"
#include "tObject1.h" // public inheritance from tObject
#include "tObject2.h" // public inheritance from tObject
#include "tObject3.h" // public inheritance from tObject
class BaseFactory
{
public:
// factory method
virtual tNode *createObject(int id)
{
if (id == 1) return new tObject1;
else return new tObject2;
}
};
class DerivedFactory: public BaseFactory
{
public:
virtual tNode *createObject(int id)
{
// Overrides the default behavior only for one type
if (id == 1) return new tObject3;
// Call the default factory method for all other types
else return BaseFactory::createObject(id);
}
};
Am I missing something?
Yes - context. Notepad_plus_Window derives from Window, and the call to Window::init() is inside of the Notepad_plus_Window::init() method:
class Notepad_plus_Window : public Window {
public:
...
void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams);
...
};
void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdLineParams *cmdLineParams)
{
...
Window::init(hInst, parent);
...
}
In this context, Notepad_plus_Window is calling the base class Window version of init().
Maybe this will confuse you less. You're missing context, at no real fault of your own.
You're not seeing the implicit this in the call.
Take the following example:
#include <cstdio>
#include <iostream>
class Foo {
public:
virtual void bar() {
std::cout << "Foo" << std::endl;
}
};
class Bar : public Foo {
public:
virtual void bar() {
std::cout << "Bar" << std::endl;
}
};
int main() {
Bar bar;
bar.bar(); //-> bar
bar.Foo::bar(); //-> foo
Bar *barp = &bar;
barp->bar(); //-> bar
barp->Foo::bar(); //-> foo
return 0;
}
In the above, we can specify the object on which to call a specific method in the class' hierarchy.
It's not a static function. It's calling a function with a specified (class) scope.
By default, init() will match functions within current class scope, if they do exist. that is an implicit this call, equals this->init(),
But with a specified class/namespace prefix, you can explicit call any particular function without dynamic binding. i.e. ::init() will call the init() function within global scope.
the following code may give you a better understanding
#include <iostream>
class A
{
public:
virtual void test()
{
std::cout << "A" << std::endl;
}
};
class B : public A
{
public:
virtual void test()
{
std::cout << "B" << std::endl;
}
};
int main()
{
A* a = new B();
a->A::test();
return 0;
}

How can an object type be unknown at compile time?

I am currently learning about dynamic binding and virtual functions. This is from Accelerated C++, chapter 13:
[...] We want to make that decision at run time. That is, we want the
system to run the right function based on the actual type of the
objects passed to the function, which is known only at run time.
I don't understand the very idea that the type of an object can be unknown at compile time. Isn't it obvious from the source code?
Not at all. Consider this example:
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { std::cerr << "In B::f()\n"; }
};
struct C : A {
virtual void f() { std::cerr << "In C::f()\n"; }
};
static void f(A &a)
{
a.f(); // How do we know which function to call at compile time?
}
int main(int,char**)
{
B b;
C c;
f(b);
f(c);
}
When the global function f is compiled, there is no way to know which function it should call. In fact, it will need to call different functions each time. The first time it is called with f(b), it will need to call B::f(), and the second time it is called with f(c) it will need to call C::f().
C++ has a concept of pointers, where the variable holds only a "handle" to an actual object. The type of the actual object is not known at compile-time, only at runtime. Example:
#include <iostream>
#include <memory>
class Greeter {
public:
virtual void greet() = 0;
};
class HelloWorld : public Greeter {
public:
void greet() {std::cout << "Hello, world!\n";}
};
class GoodbyeWorld : public Greeter {
public:
void greet() {std::cout << "Goodbye, world!\n";}
};
int main() {
std::unique_ptr<Greeter> greeter(new HelloWorld);
greeter->greet(); // prints "Hello, world!"
greeter.reset(new GoodbyeWorld);
greeter->greet(); // prints "Goodbye, world!"
}
See also: Vaughn Cato's answer, which uses references (which is another way to hold a handle to an object).
Say you have a pointer to base class pointing to a derived object
Base *pBase = new Derived;
// During compilation time, compiler looks for the method CallMe() in base class
// if defined in class Base, compiler is happy, no error
// But when you run it, the method call gets dynamically mapped to Derived::CallMe()
// ** provided CallMe() is virtual method in Base and derived class overrides it.
pBase->CallMe(); // the actual object type is known only during run-time.

Are there metaclasses or class reference in D?

Are there any system of classe reference in D? To be more accurate I look for the equivalent of the Delphi
TMyClassRef = class of TMyClass;
This would be used for a factory (just like in the Object but without using the class name):
// ideally
void AddNew(*TBaseClass APtr, /*?class_ref_type?*/ AClassType)
{
*APtr = new AClassType;
}
Currently I do this:
void AddNew(*TBaseClass APtr)
{
*APtr = new typeof(*APtr);
}
But the problem is that typeof() returns always TBaseClass and never a sub class of TBaseClass (when a sub class is passed as parameter). This is clearly a case where class references would be used in Delphi but the D language doesn't seem to have such a system.
Maybe I'm completely missing the idea in Delphi, but this seems to be what a templates are for:
import std.stdio;
class Parent {
string inherited() {
return "Hello from parent";
}
override string toString() {
return "Hello from parent";
}
}
class Child : Parent {
override string toString() {
return "Hello from child";
}
}
void add(C, P)(P* ptr) {
*ptr = new C;
}
void main() {
Parent t;
writeln(t); // prints null
add!Child(&t);
writeln(t); // prints Hello from child
writeln(t.inherited()); // prints Hello from parent
}
This way you pass in the type you want to instantiate instead of an instantiated object of that type. This should generate compile errors if C is not a child of P in add().
Edit:
If you want to be more specific with add, you could do this:
void add(T : Parent)(Parent* ptr) {
*ptr = new T;
}
To make things nicer, use an out parameter to be more idiomatic:
void add(T : Parent)(out Parent ptr) {
ptr = new T;
}
void main() {
Parent p;
add!Child(p);
}
D has no class references in the Delphi way as far as I have understood Delphi concept. If you need to make a run-time decision about object construction, object.TypeInfo may help you.
You can retrieve TypeInfo for a variable via typeid construct:
import std.stdio;
class Base
{
void f()
{
writeln("Base");
}
}
class Descendant : Base
{
override void f()
{
writeln("Descendant");
}
}
Base makeNew(Base other)
{
// cast is needed because create() returns plain Object
// we can be sure it is Base at least, though, because it was crated from Base
return cast(Base)typeid(other).create();
}
void main()
{
Descendant source = new Descendant;
Base target = makeNew(source);
// prints "Descendant"
target.f();
}
Is this code sample similar to what you want?
D generally has a very clear differentiation between run-time actions and compile-time ones. typeof works on compile-time and thus can't query "real" class type in case of hierarchies.