whypro 发表于 2010-10-13 17:29:47

把C++/CLI委托传入本地代码

C++/CLI可以直接执行C++, 这个没有问题, 那么反过来呢?
比如底层C++进行一项任务, 完成了需要通知上层的C++/CLI, 总不能在上面不停地查询吧?
通常这是通过回调来实现的, 说漂亮点就是观察者模式, 说成.net的就是委托.
而委托, 本质是就是函数指针. 以前也提到过C++委托的实现.
.net提供了一个方法把委托转换成函数指针: Marshal::GetFunctionPointerForDelegate
跟String的转换一样, 需要注意保证内存指针不会被托管机制移动/回收.
view plaincopy to clipboardprint?
// DelegateCallback.cpp : main project file.   

#include "stdafx.h"   
#include <assert.h>   

#pragma unmanaged   
typedef void (__stdcall* EventCallback)(int);   
class Native   
{   
public:   
    /// 注册回调函数   
    static void RegisterCallback(EventCallback callback)   
    {   
      assert(0 != callback);   
      ms_callback = callback;   
    }   
    /// 调用注册的回调函数   
    static void Invoke(int i)   
    {   
      assert(0 != ms_callback);   
      ms_callback(i);   
    };   

private:   
    static EventCallback ms_callback;   
};   
EventCallback Native::ms_callback = 0;   
#pragma managed   

using namespace System;   
using namespace System::Runtime::InteropServices;   

public delegate void EventDelegate(int i);   

ref class NativeInterface   
{   
public:   
    NativeInterface()   
    {   
      // 从成员函数创建一个委托   
      this->nativeCallback = gcnew EventDelegate(this, &NativeInterface::Callback);   

      // 保证委托不会被内存移动和垃圾回收掉   
      this->delegateHandle = GCHandle::Alloc(this->nativeCallback);   

      // 转换为函数指针注册   
      IntPtr ptr = Marshal::GetFunctionPointerForDelegate(this->nativeCallback);   
      Native::RegisterCallback( static_cast<EventCallback>(ptr.ToPointer()) );   
    }   

    ~NativeInterface()   
    {   
      // 释放委托句柄   
      if (this->delegateHandle.IsAllocated)   
            this->delegateHandle.Free();   
    }   

private:   
    void Callback(int i)   
    {   
      Console::WriteLine("托管命令行输出: {0}", i);   
    }   
private:   
    GCHandle delegateHandle;   
    EventDelegate^ nativeCallback;   
};   

//------------------------------------------------------------------------------   
int main(array<System::String^>^ args)   
{   
    NativeInterface^ ni = gcnew NativeInterface();   

    // 这个可以在native c++中调用   
    Native::Invoke(12345);   

    delete ni;   
    ni = nullptr;   

    return 0;   
}
// DelegateCallback.cpp : main project file.
#include "stdafx.h"
#include <assert.h>
#pragma unmanaged
typedef void (__stdcall* EventCallback)(int);
class Native
{
public:
/// 注册回调函数
static void RegisterCallback(EventCallback callback)
{
assert(0 != callback);
ms_callback = callback;
}
/// 调用注册的回调函数
static void Invoke(int i)
{
assert(0 != ms_callback);
ms_callback(i);
};
private:
static EventCallback ms_callback;
};
EventCallback Native::ms_callback = 0;
#pragma managed
using namespace System;
using namespace System::Runtime::InteropServices;
public delegate void EventDelegate(int i);
ref class NativeInterface
{
public:
NativeInterface()
{
// 从成员函数创建一个委托
this->nativeCallback = gcnew EventDelegate(this, &NativeInterface::Callback);
// 保证委托不会被内存移动和垃圾回收掉
this->delegateHandle = GCHandle::Alloc(this->nativeCallback);
// 转换为函数指针注册
IntPtr ptr = Marshal::GetFunctionPointerForDelegate(this->nativeCallback);
Native::RegisterCallback( static_cast<EventCallback>(ptr.ToPointer()) );
}
~NativeInterface()
{
// 释放委托句柄
if (this->delegateHandle.IsAllocated)
   this->delegateHandle.Free();
}
private:
void Callback(int i)
{
Console::WriteLine("托管命令行输出: {0}", i);
}
private:
GCHandle delegateHandle;
EventDelegate^ nativeCallback;
};
//------------------------------------------------------------------------------
int main(array<System::String^>^ args)
{
NativeInterface^ ni = gcnew NativeInterface();
// 这个可以在native c++中调用
Native::Invoke(12345);
delete ni;
ni = nullptr;
    return 0;
}



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xoyojank/archive/2010/10/13/5937850.aspx
页: [1]
查看完整版本: 把C++/CLI委托传入本地代码