使用托管类方法作为回调

时间:2013-11-10 17:56:52

标签: c# c++ c++-cli marshalling

我目前正在做一个小型的Midi项目,刚才我正在写一点" SharpMidi"使用C ++ / Cli中的库,可以更轻松地使用托管代码中的本机Midi函数。

我现在停留在midiInOpen功能: http://msdn.microsoft.com/en-us/library/windows/desktop/dd798458%28v=vs.85%29.aspx

从文档中可以看出,此函数需要一个非托管函数作为Callback和可选实例数据。

我设法使用管理功能指针转换为非管理功能指针 System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate 但是我现在在将this指针从我的托管类转换为非托管指针时遇到了问题,我甚至不知道它是否可能以我希望它的方式工作。

HMIDIIN _midiInDevice;

void MidiInProcNative(HMIDIIN midiInDevice, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
delegate void MidiInProc(HMIDIIN midiInDevice, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);

MidiInProc^ _midiInProc;

...

_midiInProc = gcnew MidiInDevice::MidiInProc(this, &MidiInDevice::MidiInProcNative);

cli::pin_ptr<HMIDIIN> midiInDevPtr = &_midiInDevice;
pin_ptr<???> thisPtr = this; // This is the line I'm struggling with
MMRESULT result = midiInOpen(midiInDevPtr, devId, (DWORD_PTR)System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(_midiInProc).ToPointer(), thisPtr, CALLBACK_FUNCTION);

正如您所看到的,我已尝试使用pin_ptrs,但我认为这不会起作用,因为此指针不能用于初始化任何pin_ptr。

我希望我能说清楚我想要实现的目标,也许有人可以帮助我。 问候, Xaser

1 个答案:

答案 0 :(得分:2)

  

我现在在将此指针从托管类转换为非托管指针

时遇到问题

请不要,没有必要。 miniInOpen()的 dwCallbackInstance 参数是本机C ++的便捷参数。你在静态回调函数中得到它,让你调用C ++类的实例方法。

但是委托比成员函数指针强大得多,它们已经封装了 this 。委托构造函数使用两个参数,目标对象和目标方法。这样它就可以自动调用实例方法。你已经利用了这一点,你确实传递了 this 作为第一个参数。因此,您可以确保您的MidiInProcNative()实例方法使用正确的对象引用。

只需为参数传递nullptr。