简体   繁体   中英

c++/CLI error in GChandle

I am new to C++/CLI and I facing some issues in running my application. I have a scenario where unmanaged code needs to call managed code. I am using GCHandle for that purpose. That's how my CLI class looks like

#pragma once
#include <msclr\gcroot.h>
#include "UnmanagedClass1.h"
using namespace System;

namespace Wrapper {
public ref class WrapperClass
{
private:
    UnmanagedClass::UnmanagedClass1* UnmanagedClass1obj;
    GCHandle delegateHandle_;



public:
    WrapperClass(void);
    delegate void EventDelegate(char *);
           EventDelegate^ nativeCallback_;
    void callback(char *msg);
 };
}

and the cpp file

using namespace Wrapper;

WrapperClass::WrapperClass(void)
{
UnmanagedClass1obj = new UnmanagedClass::UnmanagedClass1 ();

nativeCallback_ = gcnew EventDelegate(this, &WrapperClass::callback);

// As long as this handle is alive, the GC will not move or collect the delegate
// This is important, because moving or collecting invalidate the pointer
// that is passed to the native function below
delegateHandle_ = GCHandle::Alloc(nativeCallback_);

// This line will actually get the pointer that can be passed to
// native code
IntPtr ptr = Marshal::GetFunctionPointerForDelegate(nativeCallback_);

// Convert the pointer to the type required by the native code
UnmanagedClass1obj ->RegisterCallback( static_cast<EventCallback>(ptr.ToPointer()) );
   }

   void WrapperClass::callback(char *msg)
   {
//TDO
   }

I am getting following errors

error C2146: syntax error : missing ';' before identifier 'delegateHandle_' 
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   
error C4430: missing type specifier - int assumed. Note: C++ does not support 
error C2065: 'delegateHandle_' : undeclared identifier
error C2653: 'GCHandle' : is not a class or namespace name  
error C3861: 'Alloc': identifier not found  
error C2653: 'Marshal' : is not a class or namespace name   
error C3861: 'GetFunctionPointerForDelegate': identifier not found

Top 3 error are in .h file and rest in cpp file Did I missed some lib?

I also have few more questions regarding the implementation:

The project output will be a dll. Then how I use it to implement call back with c# code. I mean do I need to pass the c# class object as reference (how?) or some other way?

I am using char pointer to pass back to C#. Is there a better data type? Eg BSTR? Who will release the memory C#, CLI, C++?

I think you just did the hardest part of wrapper. Now, I would create a event in the wrapper to send the messages to any subscriber of it. Let me show you a code: H file

// Define out custom delegate for event
public delegate void StringEventHandler(String^ /*msg*/);

ref class WrapperClass{
  // ... rest of class declaration ...
public:
   event StringEventHandler^ MyEvent;
  // ...
}

CPP file

// ... code
void WrapperClass::callback(char* msg)
{
   // Our method to marshal to String from char*
   String^ managedString = NativeString2ManagedString(char* msg);

   // Call the event delegate
   MyEvent(managedString);
}
// ... more code

I think that the code is clear. May be your callbacks method should be a private member and just expose MyEvent as public one. To marshal between char* and String, there are a lot of examples in the web; it depend upon encoding. To subscribe to an event, create a method with the same signature of StringEventHandler:

// c++/cli
wrapperClassInstance->MyEvent += gcnew StringEventHandler(obj, OtherClass::Method);
// c#
wrapperClassInstance.MyEvent += obj.Method;

I hope this help you. -- Jairo --

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM