Haxan wrote:
Quote:
Im able to pass the delegate to managed C# function but cant pass the
CString/char * parameter(which is a parameter of this delegate).
|
OK, I modified my original example to pass a String instead of an int.
It also includes the String^ to const char* conversion. I don't see it
happening without an intermediate forwarder, which I called Thunk. It
can go to the C++/CLI DLL. In your case ManagedSender is written in C#,
but it shouldn't make any difference. The point is that ManagedSender
doesn't know anything about the receiver, it has no idea that it's
handled by an unmanaged class.
This is the best I can do to help you. I can't suggest anything that
automatically marshals the string without the intermediate Thunk object.
There may be something available that I'm not aware of.
Tom
#include "stdafx.h"
#include <vcclr.h>
#include <iostream>
using namespace System;
////////////////////////////////////////////
// C# DLL
#pragma managed
public delegate void ManagedEvent(String^ arg);
public ref class ManagedSender
// event sender
{
public:
event ManagedEvent^ SomeEvent;
void FireEvent()
{
SomeEvent("Hello");
}
};
////////////////////////////////////////////
// Mixed native C++ / C++/CLI DLL
#pragma unmanaged
class UnmanagedReceiver
{
public:
void HandleEvent(const char* arg)
{
std::cout << arg << "\n";
}
};
#pragma managed
struct StringConvAnsi
{
char *szAnsi;
StringConvAnsi(String^ s)
: szAnsi(static_cast<char*>(
Runtime::InteropServices::Marshal::StringToHGlobal Ansi(s).
ToPointer()))
{
}
~StringConvAnsi()
{
Runtime::InteropServices::Marshal::FreeHGlobal(Int Ptr(szAnsi));
}
char* c_str() const
{
return szAnsi;
}
};
ref class Thunk
// event forwarder
{
public:
Thunk(UnmanagedReceiver* A_ptr) : ptr(A_ptr) { }
void CallbackForwarder(String^ arg)
{
ptr->HandleEvent(StringConvAnsi(arg).c_str());
}
private:
UnmanagedReceiver* ptr;
};
////////////////////////////////////////////
// Test application to set up the chain of calls
#pragma managed
int main(array<String ^^args)
{
UnmanagedReceiver receiver;
ManagedSender^ sender = gcnew ManagedSender;
Thunk^ thunk = gcnew Thunk(&receiver);
sender->SomeEvent += gcnew ManagedEvent(thunk,
&Thunk::CallbackForwarder);
sender->FireEvent();
return 0;
}