Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / September 2005

Tip: Looking for answers? Try searching our database.

Callback from native C++ to managed C++

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Drew - 08 Sep 2005 16:18 GMT
I have a native C++ method that takes a function pointer as an
argument.

I've looked at the examples for getting a native C function to take a
delegate, but I just can't seem to get it to work with a C++ method.

Any ideas?

A little code to give you an idea of where I am at and what I want.

In managed.dll

#include "Native.h"

[DllImport("native.dll")]
void CNative::Test(CallBack* x); // this gives me C2761 (member
function redeclaration not allowed)

void main(void) {
 EnumReport* er = new EnumReport;
 CallBack* myCallBack = new CallBack(er, &EnumReport::Report);

 CNative native;
 native.Test(myCallBack);
}

In native.dll

typedef void (*RENAME_CALLBACK)();

extern "C"
{

class NATIVE_API CNative {
public:
    CNative(void);
    void Test(RENAME_CALLBACK pFn);
};

}
Willy Denoyette [MVP] - 08 Sep 2005 20:11 GMT
You can't call C++ member functions using PInvoke interop (DllImport), only
C style exports can be called, but when using C++/ME C++  there is no need
for PInvoke either, you can directly call the method and pass a function
pointer as argument.

Willy.

>I have a native C++ method that takes a function pointer as an
> argument.
[quoted text clipped - 36 lines]
>
> }
Drew - 08 Sep 2005 20:51 GMT
Fantastic. Thank you for the information.

I changed my code around and everything (well, almost) looks good.

If I add an argument to my function pointer such as :

typedef void (*RENAME_CALLBACK)(int x);

and I call the function like this:

void CNative::Test(RENAME_CALLBACK pFn)
{
 pFn(10);
}

I'm getting strange values for the argument. I think it has something
to do with the calling convention, but I'm not quite sure how to fix
it. I read that __gc classes are __clrcall and my native code is
__stdcall.

When I pass my function pointer into my native class :

RENAME_CALLBACK pFn = (RENAME_CALLBACK) EnumReport::Report;

CNative native;
native.Test(pFn);

I have to cast the method to RENAME_CALLBACK because it won't let me
set a method with __clrcall calling convention to RENAME_CALLBACK.

Am I on the right track?
Drew - 09 Sep 2005 17:32 GMT
Willy Denoyette [MVP] - 10 Sep 2005 00:45 GMT
> Fantastic. Thank you for the information.
>
[quoted text clipped - 27 lines]
>
> Am I on the right track?

Yes you are, but unfortunately it's not that simple in ME C++ (things are
different in C++/CLI though).

Here is is a sample that shows you how to handle the calling convention
issue...
Note that this is basically what PInvoke does....but you have more control
(and responsability) here over marshaling the arguments.

#pragma unmanaged
class Native
{
  public:
  void DoSomethingNativeAndCallUsBack( void (__stdcall *ptr) (int))
  {
  int i = 10;
   {
// Call into managed code using the callback pointer passing an int
   ptr(i);
   }
  }
};

// managed code from here
#pragma managed

public __gc class C
{
private:
// private inner non GC class used as thunk to callback into managed code
   __nogc class _C
   {
    private:
    static void __stdcall CallbackProc(int v)
    {
    m_pClass->m_cbProc->Invoke(v);
    return ;
    }
    public:
    void CallNative()
    {
    Native* n = new Native();
   n->DoSomethingNativeAndCallUsBack(_C::CallbackProc);
    }
   };
 _C* m_c;

public:
 __delegate void CbckProc(int v);
  static C* m_pClass = 0;
 C()
 {
  m_pClass = this;
  m_c = new _C();
 }
 ~C()
 {
  delete m_c;
 }
 //Managed callback method
 static void CallBack(int i)
  {
  System::Console::WriteLine(__box(i));
  }
 void DoSomething()
 {
    m_cbProc = new CbckProc(this, &C::CallBack);
    m_c->CallNative();
 }
CbckProc* m_cbProc;
};

int main()
{
  C* c = new C();
  c->DoSomething();
}

Hope this help.

Willy.
Drew - 12 Sep 2005 17:10 GMT
Thanks Willy for getting back to me.

This works like a charm.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.