我是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 ++?
答案 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 -