0
votes

I'm currently working on a little Midi Project and just now I'm writing a little "SharpMidi" Library in C++/Cli to make it easier for me to use native Midi functions from Managed code.

I'm now stuck on the midiInOpen Function: http://msdn.microsoft.com/en-us/library/windows/desktop/dd798458%28v=vs.85%29.aspx

As you can see from the documentation, this function requires an unmanaged function as Callback and optional instance data.

I managed to convert a Managed Function Pointer to an unmanaged Function Pointer using System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate but I now have problems converting the this Pointer from my managed class to an unmanaged Pointer, I don't even know if its possibly they way I want it to work.

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);

As you can see I have experimented with pin_ptrs but I don't think this will work as the this pointer can't be used to initialize any pin_ptr.

I hope I could make clear what I want to try to achieve and maybe somebody can help me out. Regards, Xaser

1

1 Answers

2
votes

I now have problems converting the this Pointer from my managed class to an unmanaged Pointer

Just don't, there's no need for it. The dwCallbackInstance argument of miniInOpen() is a convenience argument for native C++. You get it back in the static callback function, let's you call an instance method of a C++ class.

But delegates are far more powerful than member function pointers, they already encapsulate this. A delegate constructor takes two arguments, the target object and the target method. So that it can automatically call an instance method. You already took advantage of that, you indeed passed this as the first argument. So you can be sure that your MidiInProcNative() instance method uses the proper object reference.

Just pass nullptr for the argument.