Interop function definition question

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
 
P

Pavel Minaev

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.
 
S

Steven

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...
 
S

Steven

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.
 
S

Steven

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top