Interop function definition question

  • Thread starter Thread starter Steven
  • Start date Start date
S

Steven

I have a 3rd party inproc COM dll that I've used in the past to get video
from a device. The relevent parts of the COM object are a function and a
callback interface implementation class. So in unmanged world something
like this:

//Unmanaged
CCaptureCB callack;
pCapture->Connect(ip,port, &callback);

class CCaptureCB : IVideoCaptureCtrlCB
{
STDMETHODIMP ImageReady(tagTHIRDPARTYBMPINFOHEADER bmi, const BYTE*
pBuffer, DWORD BufferSize)
{
//handle the image coming in...
}
}

I added a reference to the existing unmanaged DLL and got my interop version
and away I went.
Everything seemed to be going well, but after I finished and was ready to
test I noticed that pBuffer was always 0, yet in a C++ application opened
immediately afterwards it comes in as a valid address.

The metadata shows the interop callback definition as:

//C#
[Guid("FC172CD0-142B-44C6-A106-718C4E82B58A")]
[InterfaceType(1)]
public interface IVideoCaptureCtrlCB
{
void CaptureReady(ref tagTHIRDPARTYBMPINFOHEADER bih, ref byte pBuffer,
uint BufferSize);
}

OLE/COM Object browser shows the original def as:

//C++/TypeLib
[
odl,
uuid(FC972CD0-14CB-4426-A106-718C4E82B58A),
helpstring("IVideoCaptureCtrlCB Interface")
]
interface IVideoCaptureCtrlCB : IUnknown {
HRESULT _stdcall CaptureReady(
[in] tagTHIRDPARTYBMPINFOHEADER * bih,
[in] unsigned char* pBuffer,
[in] unsigned long BufferSize);
};

I'm wondering if the problem is the "ref byte pBuffer", should it be an
IntPtr, does it matter? How can I change it? Can I write my own? If so,
how do I get the definitions of the interface, for example, below
IVideoCaptureCtrl, VideoCaptureCtrl would be undefined if I try to do it
myself:

[TypeLibType(2)]
[Guid("09CAC270-0C08-490D-B5D7-3659C23F7000")]
[ClassInterface(0)]
public class VideoCaptureCtrlClass : IVideoCaptureCtrl, VideoCaptureCtrl
{
public VideoCaptureCtrlClass();

public virtual void Connect(uint ipAddress, uint hostAddress, ushort
udpport, ushort rate, int iframesonly, IVideoCaptureCtrlCB pCallback);
public virtual void ConnectEx(uint ipAddress, uint hostAddress,
ushort udpport, ushort rate, int iframesonly, IVideoCaptureCtrlCB pCallback,
int rtp);
public virtual void Disconnect();
}

Thanks!

Steven
 
I have a 3rd party inproc COM dll that I've used in the past to get video
from a device.  The relevent parts of the COM object are a function anda
callback interface implementation class.  So in unmanged world something
like this:

//Unmanaged
CCaptureCB callack;
pCapture->Connect(ip,port, &callback);

class CCaptureCB : IVideoCaptureCtrlCB
{
  STDMETHODIMP ImageReady(tagTHIRDPARTYBMPINFOHEADER bmi, const BYTE*
pBuffer, DWORD BufferSize)
  {
        //handle the image coming in...
  }

}

I added a reference to the existing unmanaged DLL and got my interop version
and away I went.
Everything seemed to be going well, but after I finished and was ready to
test I noticed that pBuffer was always 0, yet in a C++ application opened
immediately afterwards it comes in as a valid address.

At what point were you checking the value of "pBuffer" (I mean, in C++
or C#, and if in C#, then how did you check the value?)
The metadata shows the interop callback definition as:

//C#
[Guid("FC172CD0-142B-44C6-A106-718C4E82B58A")]
[InterfaceType(1)]
public interface IVideoCaptureCtrlCB
{
    void CaptureReady(ref tagTHIRDPARTYBMPINFOHEADER bih, ref byte pBuffer,
uint BufferSize);

}

Note that this means that pBuffer is just a single byte passed by
reference, which is almost certainly not what you want. More likely
you need "byte[] pBuffer".
I'm wondering if the problem is the "ref byte pBuffer", should it be an
IntPtr, does it matter?  How can I change it?  Can I write my own?

Yes, absolutely. The simplest way is to decompile the DLL generated
from your typelib (e.g. with Reflector) and patch it as needed.
 
Note that this means that pBuffer is just a single byte passed by
reference, which is almost certainly not what you want. More likely
you need "byte[] pBuffer".

I considered that as soon as I had posted.
Yes, absolutely. The simplest way is to decompile the DLL generated
from your typelib (e.g. with Reflector) and patch it as needed.

Okay, I downloaded "Red Gate's .NET Reflector", correct one? and
found the Interop dll and drilled down and found the function but when
I select "disassemble" it just opens a pain that has a read-only display
of the information about the function with links to the types.

Do I have the right program? how do I alter the definition?

Thanks again...
 
Okay, I figured out you have to EXPORT it, change it, recompile and
re-reference.

Got that. But now, the call back function is just never being called by the
COM object, I never hit a breakpoint inside after changing the type to
byte[].

Not sure what that's about. I was getting into the callback before the
change.


I have a 3rd party inproc COM dll that I've used in the past to get video
from a device. The relevent parts of the COM object are a function and a
callback interface implementation class. So in unmanged world something
like this:

//Unmanaged
CCaptureCB callack;
pCapture->Connect(ip,port, &callback);

class CCaptureCB : IVideoCaptureCtrlCB
{
STDMETHODIMP ImageReady(tagTHIRDPARTYBMPINFOHEADER bmi, const BYTE*
pBuffer, DWORD BufferSize)
{
//handle the image coming in...
}

}

I added a reference to the existing unmanaged DLL and got my interop
version
and away I went.
Everything seemed to be going well, but after I finished and was ready to
test I noticed that pBuffer was always 0, yet in a C++ application opened
immediately afterwards it comes in as a valid address.

At what point were you checking the value of "pBuffer" (I mean, in C++
or C#, and if in C#, then how did you check the value?)
The metadata shows the interop callback definition as:

//C#
[Guid("FC172CD0-142B-44C6-A106-718C4E82B58A")]
[InterfaceType(1)]
public interface IVideoCaptureCtrlCB
{
void CaptureReady(ref tagTHIRDPARTYBMPINFOHEADER bih, ref byte pBuffer,
uint BufferSize);

}

Note that this means that pBuffer is just a single byte passed by
reference, which is almost certainly not what you want. More likely
you need "byte[] pBuffer".
I'm wondering if the problem is the "ref byte pBuffer", should it be an
IntPtr, does it matter? How can I change it? Can I write my own?

Yes, absolutely. The simplest way is to decompile the DLL generated
from your typelib (e.g. with Reflector) and patch it as needed.
 
Okay, I got it. It DID work with IntPtr. Not sure why, but I'm getting
into the function now and I have a valid pointer now.

Thanks for your help and pointed me to Reflector.

Steven


Steven said:
Okay, I figured out you have to EXPORT it, change it, recompile and
re-reference.

Got that. But now, the call back function is just never being called by
the COM object, I never hit a breakpoint inside after changing the type to
byte[].

Not sure what that's about. I was getting into the callback before the
change.


I have a 3rd party inproc COM dll that I've used in the past to get video
from a device. The relevent parts of the COM object are a function and a
callback interface implementation class. So in unmanged world something
like this:

//Unmanaged
CCaptureCB callack;
pCapture->Connect(ip,port, &callback);

class CCaptureCB : IVideoCaptureCtrlCB
{
STDMETHODIMP ImageReady(tagTHIRDPARTYBMPINFOHEADER bmi, const BYTE*
pBuffer, DWORD BufferSize)
{
//handle the image coming in...
}

}

I added a reference to the existing unmanaged DLL and got my interop
version
and away I went.
Everything seemed to be going well, but after I finished and was ready to
test I noticed that pBuffer was always 0, yet in a C++ application opened
immediately afterwards it comes in as a valid address.

At what point were you checking the value of "pBuffer" (I mean, in C++
or C#, and if in C#, then how did you check the value?)
The metadata shows the interop callback definition as:

//C#
[Guid("FC172CD0-142B-44C6-A106-718C4E82B58A")]
[InterfaceType(1)]
public interface IVideoCaptureCtrlCB
{
void CaptureReady(ref tagTHIRDPARTYBMPINFOHEADER bih, ref byte pBuffer,
uint BufferSize);

}

Note that this means that pBuffer is just a single byte passed by
reference, which is almost certainly not what you want. More likely
you need "byte[] pBuffer".
I'm wondering if the problem is the "ref byte pBuffer", should it be an
IntPtr, does it matter? How can I change it? Can I write my own?

Yes, absolutely. The simplest way is to decompile the DLL generated
from your typelib (e.g. with Reflector) and patch it as needed.
 
Back
Top