我目前正在做一个小的 Midi 项目,现在我正在用 C++/Cli 编写一个小的“SharpMidi”库,以便我可以更轻松地从托管代码使用 native Midi 函数。
我现在停留在 midiInOpen 函数上: http://msdn.microsoft.com/en-us/library/windows/desktop/dd798458%28v=vs.85%29.aspx
正如您从文档中看到的,此函数需要一个非托管函数作为回调和可选的实例数据。
我设法将托管函数指针转换为非托管函数指针使用
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_ptr 进行了试验,但我认为这不会起作用,因为 this 指针不能用于初始化任何 pin_ptr。
我希望我能说清楚我想要实现的目标,也许有人可以帮助我。 问候, 激光
最佳答案
I now have problems converting the this Pointer from my managed class to an unmanaged Pointer
别这样,没必要。 miniInOpen() 的 dwCallbackInstance 参数是 native C++ 的便利参数。你在静态回调函数中得到它,让你调用 C++ 类的实例方法。
但是委托(delegate)远比成员函数指针强大,它们已经封装了this。委托(delegate)构造函数采用两个 参数,即目标对象和目标方法。这样它就可以自动调用一个实例方法。您已经利用了这一点,您确实将 this 作为第一个参数传递了。因此,您可以确定您的 MidiInProcNative() 实例方法使用了正确的对象引用。
只需为参数传递 nullptr。
关于c# - 使用托管类方法作为回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19893056/