By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,495 Members | 1,307 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,495 IT Pros & Developers. It's quick & easy.

Problem with imported callback to C#

P: n/a
Hello,

I created a DirectShow filter which detects faces from video. Filter
exposes interface, which enables to set a callback, which is called
when a face is detected. I made an application in C# which creates a
DirectShow graph with mentioned face detector filter and calls its
interface.

Excerpt of the face detector interface declaration is as follows
(method SetCallback is important):

/// Interface for callbacks
DECLARE_INTERFACE(IFaceCB)
{
STDMETHOD(BufferCB)
(
LONGLONG FaceTime,
BYTE * pBuffer,
long BufferLen
) PURE;
};

DEFINE_GUID(IID_IFaceDetectorFilter, 0x5e3fa349, 0x566e, 0x49f7, 0x99,
0xfe, 0xb9, 0x91, 0x9b, 0xb7, 0xc4, 0x14);
DECLARE_INTERFACE_(IFaceDetectorFilter, IUnknown)
{
...

// Listener (Callback)
STDMETHOD(SetCallback)(IFaceCB * pCallback) PURE;
};

Interface IFaceDetectorFilter is implemented in the class
CFaceDetectorFilter:

class CFaceDetectorFilter : public CTransInPlaceFilter,
public IFaceDetectorFilter,
public ISpecifyPropertyPages,
public CPersistStream
{
public:

...

STDMETHODIMP SetCallback(IFaceCB * pCallback);

void DetectFace();

private:

IFaceCB* m_pCallback;
}

And implementation of the SetCallback method looks like this:

STDMETHODIMP CFaceDetectorFilter::SetCallback(IFaceCB * pCallback)
{

m_pCallback = pCallback;

return NOERROR;
}

and implementation of the method DetectFace looks like this:

void CFaceDetectorFilter::DetectFace()
{
LONGLONG timestamp; // time, when face was detected
BYTE* data; // image data of the detected face
long data_lenght; // size of the image data
...

if (m_pCallback != NULL)
m_pCallback->BufferCB(timestamp, data, data_lenght);
}

OK, and now follows code in the C# application, which calls interface
of the Face detector filter. First I had to import filter's
interfaces:

public interface IFaceCB
{
int BufferCB(long FaceTime, IntPtr pBuffer, int BufferLen);
}

[ComImport,
Guid("5E3FA349-566E-49F7-99FE-B9919BB7C414"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]
public interface IFaceDetectorFilter
{
...

[PreserveSig]
int SetCallback(IFaceCB pCallback);
}

Of course, I implemented IFaceCB interface (and its method BufferCB)
and register it with method SetCallback():

public class FaceDetector : IFaceCB
{
public int BufferCB(long theStartTime, IntPtr theDstBuffer,
int theSize)
{
...

return 0;
}

...

public int Init()
{
int hr;
IBaseFilter ibfFaceDetector = null;
IFaceDetectorFilter faceDetectorFilter = null;

...

// create face detector filter
ibfFaceDetector = (IBaseFilter) new FaceDetectorFilter();
faceDetectorFilter = (IFaceDetectorFilter)ibfFaceDetector;

// register callback
hr = faceDetectorFilter.SetCallback(this);
}

public int Run()
{
// start the DirectShow grapg, start face detection
}

...
}

After running the DirectShow graph (after call Run method), face
detection started. But when first face was detected, callback BufferCB
was called from native code and application freeze. I don't know the
reason. Can anybody help me? Did you already encounter a similar
problem when imported calleback to C# is called from native code?

Jun 27 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
BTW, I used Visual C# 2005 Express to code and build C# application

Jun 27 '07 #2

P: n/a
Usually it happens when callback declaration is using non-standard
marshalling - see CallingConvention flags defining how to deal with stack
and what are defaults. If stack doesn't correspond to calling model, you
might see this king of behavior
HTH
Alex

"Builder" <pe**********@gmail.comwrote in message
news:11**********************@n2g2000hse.googlegro ups.com...
Hello,

I created a DirectShow filter which detects faces from video. Filter
exposes interface, which enables to set a callback, which is called
when a face is detected. I made an application in C# which creates a
DirectShow graph with mentioned face detector filter and calls its
interface.

Excerpt of the face detector interface declaration is as follows
(method SetCallback is important):

/// Interface for callbacks
DECLARE_INTERFACE(IFaceCB)
{
STDMETHOD(BufferCB)
(
LONGLONG FaceTime,
BYTE * pBuffer,
long BufferLen
) PURE;
};

DEFINE_GUID(IID_IFaceDetectorFilter, 0x5e3fa349, 0x566e, 0x49f7, 0x99,
0xfe, 0xb9, 0x91, 0x9b, 0xb7, 0xc4, 0x14);
DECLARE_INTERFACE_(IFaceDetectorFilter, IUnknown)
{
...

// Listener (Callback)
STDMETHOD(SetCallback)(IFaceCB * pCallback) PURE;
};

Interface IFaceDetectorFilter is implemented in the class
CFaceDetectorFilter:

class CFaceDetectorFilter : public CTransInPlaceFilter,
public IFaceDetectorFilter,
public ISpecifyPropertyPages,
public CPersistStream
{
public:

...

STDMETHODIMP SetCallback(IFaceCB * pCallback);

void DetectFace();

private:

IFaceCB* m_pCallback;
}

And implementation of the SetCallback method looks like this:

STDMETHODIMP CFaceDetectorFilter::SetCallback(IFaceCB * pCallback)
{

m_pCallback = pCallback;

return NOERROR;
}

and implementation of the method DetectFace looks like this:

void CFaceDetectorFilter::DetectFace()
{
LONGLONG timestamp; // time, when face was detected
BYTE* data; // image data of the detected face
long data_lenght; // size of the image data
...

if (m_pCallback != NULL)
m_pCallback->BufferCB(timestamp, data, data_lenght);
}

OK, and now follows code in the C# application, which calls interface
of the Face detector filter. First I had to import filter's
interfaces:

public interface IFaceCB
{
int BufferCB(long FaceTime, IntPtr pBuffer, int BufferLen);
}

[ComImport,
Guid("5E3FA349-566E-49F7-99FE-B9919BB7C414"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]
public interface IFaceDetectorFilter
{
...

[PreserveSig]
int SetCallback(IFaceCB pCallback);
}

Of course, I implemented IFaceCB interface (and its method BufferCB)
and register it with method SetCallback():

public class FaceDetector : IFaceCB
{
public int BufferCB(long theStartTime, IntPtr theDstBuffer,
int theSize)
{
...

return 0;
}

...

public int Init()
{
int hr;
IBaseFilter ibfFaceDetector = null;
IFaceDetectorFilter faceDetectorFilter = null;

...

// create face detector filter
ibfFaceDetector = (IBaseFilter) new FaceDetectorFilter();
faceDetectorFilter = (IFaceDetectorFilter)ibfFaceDetector;

// register callback
hr = faceDetectorFilter.SetCallback(this);
}

public int Run()
{
// start the DirectShow grapg, start face detection
}

...
}

After running the DirectShow graph (after call Run method), face
detection started. But when first face was detected, callback BufferCB
was called from native code and application freeze. I don't know the
reason. Can anybody help me? Did you already encounter a similar
problem when imported calleback to C# is called from native code?


Jun 27 '07 #3

P: n/a
>After running the DirectShow graph (after call Run method), face
>detection started. But when first face was detected, callback BufferCB
was called from native code and application freeze. I don't know the
reason. Can anybody help me? Did you already encounter a similar
problem when imported calleback to C# is called from native code?

If you want to implement IFaceCB in C# you should make it a proper COM
interface and treat the callbac reference as such (calling
AddRef/Release etc).
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Jun 27 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.