Hi, experts
I have a question about COM interoperability
the scenario is unmanaged code call to managed code and then managed code callback to unmanaged code
Here are my managed code
public delegate bool CallBackCB(int x, int y);
public struct Position
{
public int x;
public int y;
}
public struct BrianRect
{
public double top;
public double left;
public double bottom;
public double right;
};
// Interface declaration.
public interface ICalculator
{
double PtInRect(ref Position pt, BrianRect rt, CallBackCB cb);
};
namespace sManagedDLL
{
// Interface implementation.
public class ManagedClass : ICalculator
{
public double PtInRect(ref Position pt , BrianRect rt, CallBackCB cb)
{
cb(pt.x,pt.y);
if (pt.x >= rt.left || pt.y >= rt.top)
return 0;
return 3;
}
}
}
and my unmanaged code is here
// Import the type library.
#import "..\\..\\sManagedDLL\sManagedDLL\bin\Debug\sManagedDLL.tlb" raw_interfaces_only
using namespace sManagedDLL;
class BrianTestCallback
{
public:
static bool WINAPI CallBackCB1(int x, int y);
};
bool WINAPI BrianTestCallback::CallBackCB1(int x, int y)
{
if(x+y>0)
return true;
return false;
}
My Problem is when use following code to call managed code
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
Position pt ;
BrianRect rect;
// Create the interface pointer.
ICalculatorPtr pICalc(__uuidof(ManagedClass));
pICalc->PtInRect(&pt,rect,BrianTestCallback::CallBackCB1,&lResult2);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
as above column
vs2008 will show the build error
error C2664: 'sManagedDLL::ICalculator::PtInRect' : cannot convert parameter 3 from 'bool (__stdcall *)(int,int)' to 'sManagedDLL::_CallBackCB *'
Do anyone know how to solve it ? Thx.
AlanPosted Aug 28, 2008, 12:32 PM
See if it will work if you change your C# interface declaration and implementation to the following:
// need this using directive
using System.Runtime.InteropServices;
// Interface declaration.
public interface ICalculator
{
double PtInRect(ref Position pt, BrianRect rt, IntPtr fp);
};
namespace sManagedDLL
{
// Interface implementation.
public class ManagedClass : ICalculator
{
public double PtInRect(ref Position pt , BrianRect rt, IntPtr fp)
{
CallBackCB cb = (CallBackCB)Marshal.GetDelegateForFunctionPointer(fp,
typeof(CallBackCB));
cb(pt.x,pt.y);
if (pt.x >= rt.left || pt.y >= rt.top)
return 0;
return 3;
}
}
}
aamir khanPosted Apr 7, 2010, 3:24 AM
I have a similiar question i hope you can help me.
I have a dll in C# and i need to call in VBA (MS Access).
VBA code will be event listener raised in C# dll. I don't want to use WithEvents in VBA (ideally).
Can i pass VBA function address using AddressOf in C# dll and call this function from C# dll.
Can you please give me a hint or a simple code explain me how can i do it.
Thanks
Aamir
BigPosted Aug 28, 2008, 11:19 PM