GChandle中的c ++ / CLI错误

时间:2013-08-25 16:22:14

标签: c# callback c++-cli command-line-interface

我是C ++ / CLI的新手,我在运行应用程序时遇到了一些问题。 我有一个非托管代码需要调用托管代码的场景。我正在为此目的使用GCHandle。 这就是我的CLI类的样子

#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);
 };
}

和cpp文件

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
   }

我收到以下错误

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

前3个错误在.h文件中,并在cpp文件中休息 我错过了一些lib吗?

我还有更多关于实施的问题:

项目输出将是一个DLL。然后我如何使用它来实现c#代码的回调。我的意思是我需要传递c#类对象作为参考(如何?)或其他方式?

我使用char指针传回C#。有更好的数据类型吗?比如BSTR?谁将释放内存C#,CLI,C ++?

1 个答案:

答案 0 :(得分:0)

我认为你刚刚完成了包装器中最困难的部分。现在,我将在包装器中创建一个事件,以将消息发送给它的任何订阅者。我来给你看一个代码: H档

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

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

CPP文件

// ... 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

我认为代码很清楚。可能是你的回调方法应该是私有成员,只是将MyEvent公开为公共成员。要在char *和String之间编组,Web中有很多例子;它取决于编码。 要订阅事件,请创建一个具有相同签名StringEventHandler的方法:

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

我希望这对你有所帮助。 - Jairo -