Python to C++: From Deriv, to Base, to Deriv again - c++

I'm using Boost.Python to expose my C++ code to Python. I've encountered a difficulty related to having an object passed from one language to the other multiple times. Here's what I want to do:
The C++ code
class Base
{
public:
void baseTest() {
std::cout << "Base::basetest()";
}
};
class Deriv
: public Base
{
public:
void derivTest() {
std::cout << "Deriv::derivTest()";
}
};
void call(Base& b, boost::python::object func)
{
func(b);
}
BOOST_PYTHON_MODULE(event)
{
using namespace boost;
using namespace boost::python;
class_<Base>("Base")
.def("baseTest", &Base::baseTest)
;
class_<Deriv, bases<Base>>("Deriv")
.def("derivTest", &Deriv::derivTest)
;
def("call", call);
}
Python code
from event import *
def callback(deriv):
deriv.baseTest() # works fine
deriv.derivTest() # crash!
def run():
d = Deriv()
call(d, callback)
What I want to happen
C++: Calls the run() function defined in Python. (No problem here)
Python: run() creates a new Deriv object; it passes it and a function object, callback, back to C++, through the call function. (Also okay)
C++: call() takes the Deriv object as a Base&. It passes the Base-reference to the Python callback it received through the second parameter.
Python: The callback receives the Base object from C++. However, it expects it to be a Deriv: if I call derivTest() the program crashes. However, if I call baseTest(), it doesn't crash.
How can I make the callback not crash?

Thanks for the comments, I found the solution to this. It's actually quite simple, you just have to wrap the Base object in a shared_ptr instead of passing it by reference, like this:
void call(boost::shared_ptr<Base> b, boost::python::object func)
{
func(b);
}
But be careful about something. I tried to used std::shared_ptr that comes with Visual C++ 2010 Express (the 'memory' header) and it caused a crash. I had to use the boost::shared_ptr for it to work. (I'm using version 1.46.1 of Boost.)

Related

Call a managed class member function from an unmanaged class member [duplicate]

How do I pass a function pointer from managed C++ (C++/CLI) to an unmanaged method? I read a few articles, like this one from MSDN, but it describes two different assemblies, while I want only one.
Here is my code:
1) Header (MyInterop.ManagedCppLib.h):
#pragma once
using namespace System;
namespace MyInterop { namespace ManagedCppLib {
public ref class MyManagedClass
{
public:
void DoSomething();
};
}}
2) CPP Code (MyInterop.ManagedCppLib.cpp)
#include "stdafx.h"
#include "MyInterop.ManagedCppLib.h"
#pragma unmanaged
void UnmanagedMethod(int a, int b, void (*sum)(const int))
{
int result = a + b;
sum(result);
}
#pragma managed
void MyInterop::ManagedCppLib::MyManagedClass::DoSomething()
{
System::Console::WriteLine("hello from managed C++");
UnmanagedMethod(3, 7, /* ANY IDEA??? */);
}
I tried creating my managed delegate and then I tried to use Marshal::GetFunctionPointerForDelegate method, but I couldn't compile.
Yes, you want Marshal::GetFunctionPointerForDelegate(). Your code snippet is missing the managed function you'd want to call, I just made one up. You will also have to declare the managed delegate type and create an instance of it before you can get a function pointer. This worked well:
#include "stdafx.h"
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed(push, off)
typedef void (* UnmanagedSummer)(int arg);
void UnmanagedMethod(int a, int b, UnmanagedSummer sum)
{
int result = a + b;
sum(result);
}
#pragma managed(pop)
ref class Test {
delegate void ManagedSummer(int arg);
public:
static void Run() {
Test^ t = gcnew Test();
ManagedSummer^ managed = gcnew ManagedSummer(t, &Sum);
IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(managed);
UnmanagedSummer functionPointer = static_cast<UnmanagedSummer>(stubPointer.ToPointer());
UnmanagedMethod(1, 2, functionPointer);
GC::KeepAlive(managed); // Important: ensure stub can't be collected while native code is running
System::Diagnostics::Debug::Assert(t->summed == 3);
}
void Sum(int arg) {
summed += arg;
}
int summed;
};
int main(array<System::String ^> ^args)
{
Test::Run();
return 0;
}
Here's another way to do it based on my experiences implementing a .NET wrapper in C++/CLI around the CartoType C++ map rendering library. This is tested and working code.
The C++ API has an asynchronous Find function which takes a callback:
TResult CartoType::CFramework::FindAsync(FindAsyncCallBack aCallBack,const TFindParam& aFindParam,bool aOverride = false);
The callback is a function of this type:
using FindAsyncCallBack = std::function<void(std::unique_ptr<CMapObjectArray> aMapObjectArray)>;
The task is to provide a .NET wrapper for this function by adding C++/CLI code to the existing wrapper system. First I define a suitable delegate type for my .NET function (an equivalent to FindAsyncCallback in the C++ API):
public delegate void FindAsyncDelegate(MapObjectList^ aMapObjectList);
The signature of the .NET function is thus:
Result FindAsync(FindAsyncDelegate^ aDelegate,FindParam^ aFindParam,bool aOverride);
The main implementation problem to be solved is how to call the native C++ function and provide a native callback function which can then call the delegate passed in by the caller of the .NET function. An associated task is to keep the delegate and the native callback function object alive until the asynchronous function's thread has done its job. Here's how it's done.
I define a C++/CLI delegate type that's the same as the C++ callback function type, and a class to hold the delegate passed in by the caller to the .NET function (of type FindAsyncDelegate), and a delegate of the type to be passed to C++ (of type NativeAsyncHandler):
delegate void NativeAsyncHandler(std::unique_ptr<CMapObjectArray> aMapObjectArray);
ref class FindAsyncHelper
{
public:
FindAsyncHelper(Framework^ aFramework,FindAsyncDelegate^ aDelegate):
m_framework(aFramework),
m_delegate(aDelegate)
{
}
void Handler(std::unique_ptr<CMapObjectArray> aMapObjectArray)
{
MapObjectList^ o = gcnew MapObjectList;
SetMapObjectList(m_framework,o,*aMapObjectArray);
m_delegate(o);
// Remove this object from the list held by the framework so that it can be deleted.
m_framework->m_find_async_helper_list->Remove(this);
}
Framework^ m_framework;
FindAsyncDelegate^ m_delegate;
NativeAsyncHandler^ m_native_handler;
};
The idea is that we create a FindAsyncHelper object with the two delegates in it, then call the native FindAsync function with the native delegate, arranged to call Handler(), which then calls the original caller's delegate.
And here is how it's implemented:
typedef void(*FIND_ASYNC_CALLBACK)(std::unique_ptr<CMapObjectArray> aMapObjectArray);
Result Framework::FindAsync(FindAsyncDelegate^ aDelegate,FindParam^ aFindParam,bool aOverride)
{
if (aDelegate == nullptr || aFindParam == nullptr)
return Result::ErrorInvalidArgument;
TFindParam param;
SetFindParam(param,aFindParam);
FindAsyncHelper^ h = gcnew FindAsyncHelper(this,aDelegate);
h->m_native_handler = gcnew NativeAsyncHandler(h,&FindAsyncHelper::Handler);
IntPtr p = Marshal::GetFunctionPointerForDelegate(h->m_native_handler);
FIND_ASYNC_CALLBACK f = static_cast<FIND_ASYNC_CALLBACK>(p.ToPointer());
TResult error = m_framework->FindAsync(f,param,aOverride);
// Keep h alive by adding it to a list.
m_find_async_helper_list->Add(h);
return (Result)(int)error;
}
Some notes:
The statements
FindAsyncHelper^ h = gcnew FindAsyncHelper(this,aDelegate);
h->m_native_handler = gcnew NativeAsyncHandler(h,&FindAsyncHelper::Handler);
create a FindAsyncHandler object and store a native handler object in it; keeping it here means we only have one object to keep alive, the FindAsyncHandler. The next statements:
IntPtr p = Marshal::GetFunctionPointerForDelegate(h->m_native_handler);
FIND_ASYNC_CALLBACK f = static_cast<FIND_ASYNC_CALLBACK>(p.ToPointer());
get a function pointer that can be passed to native code, and cast it to the right function pointer type. We can't cast it directly to the std::function type used in FindAsyncCallback, so the cumbersome extra typedef is necessary.
At last the native FindAsync function can be called:
TResult error = m_framework->FindAsync(f,param,aOverride);
And then, to make sure the various callback functions stay alive, the FindAsyncHandler is added to a list owned by the main framework object:
m_find_async_helper_list->Add(h);
It is taken off the list when the task is completed and FindAsyncHelper::Handler is called.

Embarcadero TThread: Pass TThreadMethod in C++

Edit:
Now that I have a better idea of what is going on, I think I can better phrase this question so it is more useful.
I am trying to replicate the following delphi code in C++
TThread.Queue(nil,
procedure
begin
LogMessage("test");
end
);
The purpose of the code is to call a method which updates a TMemo on a form in a thread safe manner. Here is the C++ version of the method I am trying to call with Thread.Queue
void __fastcall TClientForm::LogMessage( String message )
{
MemoLog->Lines->Add( message );
}
Because I am using a BCC32 compiler without CLANG enhancements, using a Lambda is not an option. Instead according to this documentation I need to create a class which inherits from TThreadProcedure which overrides the Invoke() method to do the work I need done. Then I can pass an instance of that class into TThread::Queue.
I created the following class which inherits TThreadProcuedure and contains an invoke method.
class TMyThreadProcedure : TThreadProcedure
{
void __fastcall Invoke( String message );
};
However, since TThreadProcedure is an abstract class, I cannot simply create an instance of it to pass into TThread::Queue. What is the proper way to inherit from TThreadProcedure and define a function to be called when I pass an instance of my class into TThread::Queue?
As stated in the documentation:
How to Handle Delphi Anonymous Methods in C++
You have two choices:
derive a class 1 that implements the appropriate interface (in this case, Classes::TThreadProcedure), overriding the Invoke() method to do your desired work. You can then pass an instance of that class to TThread::Queue(). For example:
class TLogMessageRef : public TCppInterfacedObject<Classes::TThreadProcedure>
{
private:
TClientForm *form;
public:
TLogMessageRef(TClientForm* _form) : form(_form) {}
INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
void __fastcall Invoke()
{
form->LogMessage("test");
}
};
TThread::Queue(NULL,
Classes::_di_TThreadProcedure(
new TLogMessageRef(this)
)
);
(1 the use of TCppInterfacedObject and INTFOBJECT_IMPL_IUNKNOWN is covered elsewhere in the documentation: Inheritance and Interfaces)
The documentation also provides a reusable TMethodRef class to help with the implementation, if you need to use anonymous methods/procedures in multiple places of your code:
Using a Functor (Function Object)
For example:
struct LogMsg
{
TClientForm* form;
LogMsg(TClientForm *_form) : form(_form) {}
void operator()()
{
form->LogMessage("test");
}
};
typedef TMethodRef<Classes::TThreadProcedure, LogMsg, void> MyMethRef;
TThread::Queue(NULL,
Classes::_di_TThreadProcedure(
new MyMethRef(
LogMsg(this)
)
)
);
in the Clang-based C++11 compilers only, you can use a C++ lambda anywhere an anonymous procedure/method is expected:
TThread::Queue(NULL,
[this]() -> void { LogMessage("test"); }
);

C++ - Adding standalone callback that invokes a method in the calling class

I have a managed C++ object that makes a call to an unmanaged API with a function pointer. Here is the setup:
The *.h file:
namespace MyNamespace
{
void MyStandaloneCallback(void* obj) {
EventArgs^ args = gcnew EventArgs();
((MyClass*)obj)->OnReceived(args);
}
void MyClass::OnReceived(EventArgs^ args) {
...
}
}
I'm having trouble figuring out the proper way to marshal the pointer to my calling object (MyObject) on the callback that is defined (at top) outside the object. Making the object static is not an option. Any ideas? Thanks.

JNI C++ Callbacks

I have a c++ function which accepts a lambda as a parameter. This function calls a piece of java code.
I was wondering how would I get the java code to call the lambda once it's done, in effect calling back to the C++ code.
JavaCPP does that. For example, the following code in C++:
#include "jniFoo.h"
int main() {
JavaCPP_init(0, NULL);
foo(6, 7);
}
With this Java class:
import com.googlecode.javacpp.*;
import com.googlecode.javacpp.annotation.*;
public class Foo {
public static class Callback extends FunctionPointer {
public #Name("foo") void call(int a, int b) {
System.out.println("bar " + a * b);
}
}
}
Produces the following output:
bar 42
Java does not know C++ or lambdas. You should prepare a general C callback that will know which lambda to execute.

C++: static function wrapper that routes to member function?

I've tried all sorts of design approaches to solve this problem, but I just can't seem to get it right.
I need to expose some static functions to use as callback function to a C lib. However, I want the actual implementation to be non-static, so I can use virtual functions and reuse code in a base class. Such as:
class Callbacks {
static void MyCallBack() { impl->MyCallBackImpl(); }
...
class CallbackImplBase {
virtual void MyCallBackImpl() = 0;
However I try to solve this (Singleton, composition by letting Callbacks be contained in the implementor class, etc) I end up in a dead-end (impl usually ends up pointing to the base class, not the derived one).
I wonder if it is at all possible or if I'm stuck with creating some sort of helper functions instead of using inheritance?
Problem 1:
Though it may look and seem to work on your setup this is not guaranteed to work as the C++ ABI is not defined. So technically you can not use C++ static member functions as functions pointers to be used by C code.
Problem 2:
All C callacks (that I know of) allow you to pass user data back as a void*. You can use this as the pointer to your object that has the virtual method. BUT You must make sure you use dynamic_cast<>() to the base class (the one with the virtual method used in the callback) before it is converted into the void* otherwise the pointer at the other end may not be interpreted correctly (especially if there is multiple inheritance involved).
Problem 3:
Exceptions: C is not designed to work with exceptions (especially old C libraries with callbacks). So don't expect exceptions that escape your callback to provide anything meaningful to the caller (they are more likely to result in application termination).
Solution:
What you need to do is use extern "C" function as the callback that calls the virtual method on an object of know type and throws away all exceptions.
An example for the C pthread routines
#include <iostream>
extern "C" void* start_thread(void* data);
class Work
{
public:
virtual ~Work() {}
virtual void doWork() = 0;
};
/*
* To be used as a callback for C code this MUST be declared as
* with extern "C" linkage to make sure the calling code can
* correctly call it
*/
void* start_thread(void* data)
{
/*
* Use reinterpret_cast<>() because the only thing you know
* that you can do is cast back to a Work* pointer.
*
*/
Work* work = reinterpret_cast<Work*>(data);
try
{
work->doWork();
}
catch(...)
{
// Never let an exception escape a callback.
// As you are being called back from C code this would probably result
// in program termination as the C ABI does not know how to cope with
// exceptions and thus would not be able to unwind the call stack.
//
// An exception is if the C code had been built with a C++ compiler
// But if like pthread this is an existing C lib you are unlikely to get
// the results you expect.
}
return NULL;
}
class PrintWork: public Work
{
public:
virtual void doWork()
{
std::cout << "Hi \n";
}
};
int main()
{
pthread_t thread;
PrintWork printer;
/*
* Use dynamic_cast<>() here because you must make sure that
* the underlying routine receives a Work* pointer
*
* As it is working with a void* there is no way for the compiler
* to do this intrinsically so you must do it manually at this end
*/
int check = pthread_create(&thread,NULL,start_thread,dynamic_cast<Work*>(&printer));
if (check == 0)
{
void* result;
pthread_join(thread,&result);
}
}
It's possible. Perhaps there's a problem on how you're initializing the concrete implementation?
In fact, I remember one library that does something very similar to this. You might find it usefull to take a look at libxml++ source code. It's built on top of libxml, which is a C library.
libxml++ uses a struct of static functions to handle the callbacks. For customization, the design allows the user to provide (through virtual functions) his/her own implementations to which the callbacks are then forwarded. I guess this is pretty much your situation.
Something like the below. The singleton is in class Callback, the Instance member will return a statically allocated reference to a CallbackImpl class. This is a singleton because the reference will only be initialised once when the function is first called. Also, it must be a reference or a pointer otherwise the virtual function will not work.
class CallbackImplBase
{
public:
virtual void MyCallBackImpl() = 0;
};
class CallbackImpl : public CallbackImplBase
{
public:
void MyCallBackImpl()
{
std::cout << "MyCallBackImpl" << std::endl;
}
};
class Callback
{
public:
static CallbackImplBase & Instance()
{
static CallbackImpl instance;
return instance;
}
static void MyCallBack()
{
Instance().MyCallBackImpl();
}
};
extern "C" void MyCallBack()
{
Callback::MyCallBack();
}
Are any of the parameters passed to the callback function user defined? Is there any way you can attach a user defined value to data passed to these callbacks? I remember when I implemented a wrapper library for Win32 windows I used SetWindowLong() to attach a this pointer to the window handle which could be later retrieved in the callback function. Basically, you need to pack the this pointer somewhere so that you can retrieve it when the callback gets fired.
struct CALLBACKDATA
{
int field0;
int field1;
int field2;
};
struct MYCALLBACKDATA : public CALLBACKDATA
{
Callback* ptr;
};
registerCallback( Callback::StaticCallbackFunc, &myCallbackData, ... );
void Callback::StaticCallbackFunc( CALLBACKDATA* pData )
{
MYCALLBACKDATA* pMyData = (MYCALLBACKDATA*)pData;
Callback* pCallback = pMyData->ptr;
pCallback->virtualFunctionCall();
}