2013-08-25 83 views
0

我是C++/CLI的新手,我在運行我的應用程序時遇到了一些問題。 我有一個場景,非託管代碼需要調用託管代碼。我正在使用GCHandle。 這是我的CLI類看起來像GChandle中的C++/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文件 我錯過了一些庫?

我也有幾個關於實施更多的問題:

項目的產出將是一個DLL。然後,我如何使用它來實現使用C#代碼進行回調。我的意思是我是否需要傳遞c#類對象作爲參考(如何?)或其他方式?

我正在使用字符指針傳遞迴C#。有更好的數據類型嗎?例如BSTR?誰將釋放內存C#,CLI,C++?

+1

GCHandle和Marshal位於System :: Runtime :: InteropServices命名空間中。只需在源代碼文件的頂部添加* using *指令即可。 –

+0

謝謝,所有的錯誤消失了......把它作爲答案。而且,plz可以幫助解決問題的其餘部分。 – user2692032

回答

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之間編組,網絡中有很多示例;它取決於編碼。 要訂閱事件,創建方法與StringEventHandler的相同簽名:

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

我希望這可以幫助您。 - Jairo -