strange problem occur while trying to access member function through static function 
Author Message
 strange problem occur while trying to access member function through static function

i try to use a c library which require me to pass a function pointer
as callback. hence, i build a static function inside a class .

however, i face a very strange problem while trying to access a member
function through that static function with the following trick.

i have the following classes:
CXFaceRecognitionDlg - main dialog class and with a static CPicture
control
CPicture - static control derived from CStatic
CFaceDetectionManager - generic class

in CXFaceRecognitionDlg.h
-------------------------
class CXFaceRecognitionDlg : public CDialog
{
public:
        bool GetIsCaptureDetectedFace(){ return m_bIsCaptureDetectedFace; }

// Dialog Data
        //{{AFX_DATA(CXFaceRecognitionDlg)
        enum { IDD = IDD_XFACERECOGNITION_DIALOG };
        CPicture        m_Picture;
protected:
        bool m_bIsCaptureDetectedFace;
-------------------------

in CXFaceRecognitionDlg.cpp
---------------------------
BOOL CXFaceRecognitionDlg::OnInitDialog()
{
        //this callback will process every frame
        cvcamSetProperty(0, CVCAM_PROP_CALLBACK, CPicture::callback);

        m_bIsCaptureDetectedFace = true;

Quote:
}

void CXFaceRecognitionDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CXFaceRecognitionDlg)
        DDX_Control(pDX, IDC_PICTURE, m_Picture);
        //}}AFX_DATA_MAP
Quote:
}

---------------------------

in CPicture.h
-------------
class CPicture : public CStatic
{
// Construction
public:
        static void callback(IplImage* image);

protected:
        CFaceDetectionManager* m_pFaceDetectionManager;
        static CFaceDetectionManager* m_spFaceDetectionManager;
-------------

in CPicture.cpp
---------------
CFaceDetectionManager* CPicture::m_spFaceDetectionManager = NULL;

CPicture::CPicture()
{
        try
        {
                m_pFaceDetectionManager = new CFaceDetectionManager(this);
        }
        catch(const char* c)
        {
                MessageBox(c);
                m_pFaceDetectionManager = NULL;
        }

        // I NEED THIS TO ENABLE ME TO ACCESS MEMBER FUNCTION THROUGH STATIC
FUNCTION
        m_spFaceDetectionManager = m_pFaceDetectionManager;

Quote:
}

void CPicture::callback(IplImage* image)
{
        // THIS IS THE WAY I ACCESS MEMBER FUNCTION THROUGH STATIC FUNCTION
        if(m_spFaceDetectionManager != NULL)
                m_spFaceDetectionManager->DetectAndDrawFaces(video_image);
Quote:
}

---------------

in CFaceDetectionManager.h
--------------------------
class CFaceDetectionManager  
{
// Construction
public:
        CFaceDetectionManager(CPicture* pParent, const char
*classifier_cascade_path = "<default_face_cascade>");   // standard
constructor
        void DetectAndDrawFaces( IplImage* img );
protected:
        CPicture* m_pParent;
--------------------------

in CFaceDetectionManager.cpp
----------------------------
CFaceDetectionManager::CFaceDetectionManager( CPicture* pParent, const
char *classifier_cascade_path)
{
        m_pParent = pParent;

Quote:
}

void CFaceDetectionManager::DetectAndDrawFaces( IplImage* img )
{                                       if(((CXFaceRecognitionDlg*)(m_pParent->GetParent()))->GetIsCaptureDetectedFace())
                                {
                                }
Quote:
}

----------------------------

The strange problem occurs here. i realize that the line of code
if(((CXFaceRecognitionDlg*)(m_pParent->GetParent()))->GetIsCaptureDetectedFace())

isn't getting result "true", but it is getting result "false".
although, i oledi explicitly set m_bIsCaptureDetectedFace into "true"
during the initialize of dialog box.

can anyone tell me why this strange situation happen? this really
getting me crazy :(

thank you.

regards
yccheok



Sun, 27 Nov 2005 20:34:17 GMT  
 strange problem occur while trying to access member function through static function
Cheok  treat static functions as if they not part of the class, other than
they can see typedefs.

When you call your Face Engine, pass in THIS and then pass this to the
static function callback and use it to get to dialog.

Why use a callback?



Quote:
> i try to use a c library which require me to pass a function pointer
> as callback. hence, i build a static function inside a class .

> however, i face a very strange problem while trying to access a member
> function through that static function with the following trick.

> i have the following classes:
> CXFaceRecognitionDlg - main dialog class and with a static CPicture
> control
> CPicture - static control derived from CStatic
> CFaceDetectionManager - generic class

> in CXFaceRecognitionDlg.h
> -------------------------
> class CXFaceRecognitionDlg : public CDialog
> {
> public:
> bool GetIsCaptureDetectedFace(){ return m_bIsCaptureDetectedFace; }

> // Dialog Data
> file://{{AFX_DATA(CXFaceRecognitionDlg)
> enum { IDD = IDD_XFACERECOGNITION_DIALOG };
> CPicture m_Picture;
> protected:
> bool m_bIsCaptureDetectedFace;
> -------------------------

> in CXFaceRecognitionDlg.cpp
> ---------------------------
> BOOL CXFaceRecognitionDlg::OnInitDialog()
> {
> file://this callback will process every frame
> cvcamSetProperty(0, CVCAM_PROP_CALLBACK, CPicture::callback);

> m_bIsCaptureDetectedFace = true;
> }

> void CXFaceRecognitionDlg::DoDataExchange(CDataExchange* pDX)
> {
> CDialog::DoDataExchange(pDX);
> file://{{AFX_DATA_MAP(CXFaceRecognitionDlg)
> DDX_Control(pDX, IDC_PICTURE, m_Picture);
> file://}}AFX_DATA_MAP
> }
> ---------------------------

> in CPicture.h
> -------------
> class CPicture : public CStatic
> {
> // Construction
> public:
> static void callback(IplImage* image);

> protected:
> CFaceDetectionManager* m_pFaceDetectionManager;
> static CFaceDetectionManager* m_spFaceDetectionManager;
> -------------

> in CPicture.cpp
> ---------------
> CFaceDetectionManager* CPicture::m_spFaceDetectionManager = NULL;

> CPicture::CPicture()
> {
> try
> {
> m_pFaceDetectionManager = new CFaceDetectionManager(this);
> }
> catch(const char* c)
> {
> MessageBox(c);
> m_pFaceDetectionManager = NULL;
> }

> // I NEED THIS TO ENABLE ME TO ACCESS MEMBER FUNCTION THROUGH STATIC
> FUNCTION
> m_spFaceDetectionManager = m_pFaceDetectionManager;
> }

> void CPicture::callback(IplImage* image)
> {
> // THIS IS THE WAY I ACCESS MEMBER FUNCTION THROUGH STATIC FUNCTION
> if(m_spFaceDetectionManager != NULL)
> m_spFaceDetectionManager->DetectAndDrawFaces(video_image);
> }
> ---------------

> in CFaceDetectionManager.h
> --------------------------
> class CFaceDetectionManager
> {
> // Construction
> public:
> CFaceDetectionManager(CPicture* pParent, const char
> *classifier_cascade_path = "<default_face_cascade>"); // standard
> constructor
> void DetectAndDrawFaces( IplImage* img );
> protected:
> CPicture* m_pParent;
> --------------------------

> in CFaceDetectionManager.cpp
> ----------------------------
> CFaceDetectionManager::CFaceDetectionManager( CPicture* pParent, const
> char *classifier_cascade_path)
> {
> m_pParent = pParent;
> }

> void CFaceDetectionManager::DetectAndDrawFaces( IplImage* img )

if(((CXFaceRecognitionDlg*)(m_pParent->GetParent()))->GetIsCaptureDetectedFa
ce())
Quote:
> {
> }
> }
> ----------------------------

> The strange problem occurs here. i realize that the line of code

if(((CXFaceRecognitionDlg*)(m_pParent->GetParent()))->GetIsCaptureDetectedFa
ce())

- Show quoted text -

Quote:

> isn't getting result "true", but it is getting result "false".
> although, i oledi explicitly set m_bIsCaptureDetectedFace into "true"
> during the initialize of dialog box.

> can anyone tell me why this strange situation happen? this really
> getting me crazy :(

> thank you.

> regards
> yccheok



Sun, 27 Nov 2005 23:10:56 GMT  
 strange problem occur while trying to access member function through static function
It isn't a strange problem at all. You can't access a member variable from a static
function. This is how C++ is designed to work; there is no 'this' pointer to a static
function, so no way to access a nonstatic member variable. You can pass the 'this' pointer
explicitly into a function and cast it (see my essay on callbacks on my MVP Tips site),
but without that trick, you can't access a member variable because there is no object
involved.

When you declare a static variable, it is common to all incarnations. Overall this is a
very bad way to handle the problem. You would not be able to have more than one instance
of the class. So it is a very bad habit to get into.

In a well-designed system, the callbacks allow you to specify one or more parameters to
the callback at the time you assign the function.

Do you have any control over the lplImage object, or is that something that is owned by
the library?
                                joe


Quote:
>i try to use a c library which require me to pass a function pointer
>as callback. hence, i build a static function inside a class .

>however, i face a very strange problem while trying to access a member
>function through that static function with the following trick.

>i have the following classes:
>CXFaceRecognitionDlg - main dialog class and with a static CPicture
>control
>CPicture - static control derived from CStatic
>CFaceDetectionManager - generic class

>in CXFaceRecognitionDlg.h
>-------------------------
>class CXFaceRecognitionDlg : public CDialog
>{
>public:
>    bool GetIsCaptureDetectedFace(){ return m_bIsCaptureDetectedFace; }

>// Dialog Data
>    //{{AFX_DATA(CXFaceRecognitionDlg)
>    enum { IDD = IDD_XFACERECOGNITION_DIALOG };
>    CPicture        m_Picture;
>protected:
>    bool m_bIsCaptureDetectedFace;
>-------------------------

>in CXFaceRecognitionDlg.cpp
>---------------------------
>BOOL CXFaceRecognitionDlg::OnInitDialog()
>{
>    //this callback will process every frame
>    cvcamSetProperty(0, CVCAM_PROP_CALLBACK, CPicture::callback);

>    m_bIsCaptureDetectedFace = true;
>}

>void CXFaceRecognitionDlg::DoDataExchange(CDataExchange* pDX)
>{
>    CDialog::DoDataExchange(pDX);
>    //{{AFX_DATA_MAP(CXFaceRecognitionDlg)
>    DDX_Control(pDX, IDC_PICTURE, m_Picture);
>    //}}AFX_DATA_MAP
>}
>---------------------------

>in CPicture.h
>-------------
>class CPicture : public CStatic
>{
>// Construction
>public:
>    static void callback(IplImage* image);

>protected:
>    CFaceDetectionManager* m_pFaceDetectionManager;
>    static CFaceDetectionManager* m_spFaceDetectionManager;
>-------------

>in CPicture.cpp
>---------------
>CFaceDetectionManager* CPicture::m_spFaceDetectionManager = NULL;

>CPicture::CPicture()
>{
>    try
>    {
>            m_pFaceDetectionManager = new CFaceDetectionManager(this);
>    }
>    catch(const char* c)
>    {
>            MessageBox(c);
>            m_pFaceDetectionManager = NULL;
>    }

>    // I NEED THIS TO ENABLE ME TO ACCESS MEMBER FUNCTION THROUGH STATIC
>FUNCTION
>    m_spFaceDetectionManager = m_pFaceDetectionManager;
>}

>void CPicture::callback(IplImage* image)
>{
>    // THIS IS THE WAY I ACCESS MEMBER FUNCTION THROUGH STATIC FUNCTION
>    if(m_spFaceDetectionManager != NULL)
>            m_spFaceDetectionManager->DetectAndDrawFaces(video_image);
>}
>---------------

>in CFaceDetectionManager.h
>--------------------------
>class CFaceDetectionManager  
>{
>// Construction
>public:
>    CFaceDetectionManager(CPicture* pParent, const char
>*classifier_cascade_path = "<default_face_cascade>");       // standard
>constructor
>    void DetectAndDrawFaces( IplImage* img );
>protected:
>    CPicture* m_pParent;
>--------------------------

>in CFaceDetectionManager.cpp
>----------------------------
>CFaceDetectionManager::CFaceDetectionManager( CPicture* pParent, const
>char *classifier_cascade_path)
>{
>    m_pParent = pParent;
>}

>void CFaceDetectionManager::DetectAndDrawFaces( IplImage* img )
>{                                           if(((CXFaceRecognitionDlg*)(m_pParent->GetParent()))->GetIsCaptureDetectedFace())
>                            {
>                            }
>}
>----------------------------

>The strange problem occurs here. i realize that the line of code
>if(((CXFaceRecognitionDlg*)(m_pParent->GetParent()))->GetIsCaptureDetectedFace())

****
I have no idea what this code could possibly be attempting to do. If you have a parent
window, the child has no business knowing what kind of window it is, or what its methods
are. Send a message to the parent and let it do what it is supposed to do. This is a
horrible piece of code. Get rid of it. I wouldn't even attempt to figure out what is going
on here. I'd rewrite it before attempting to figure out what problem existed. Essentially,
any time you think you need to know what your parent is or call a method in it, you are
wrong. You need to send a message.. Think about abstraction boundaries and modularity.
****

Quote:

>isn't getting result "true", but it is getting result "false".
>although, i oledi explicitly set m_bIsCaptureDetectedFace into "true"
>during the initialize of dialog box.

>can anyone tell me why this strange situation happen? this really
>getting me crazy :(

>thank you.

>regards
>yccheok

Joseph M. Newcomer [MVP]

Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Mon, 28 Nov 2005 05:03:13 GMT  
 strange problem occur while trying to access member function through static function

Quote:
> It isn't a strange problem at all. You can't access a member variable from a static
> function. This is how C++ is designed to work; there is no 'this' pointer to a static
> function, so no way to access a nonstatic member variable. You can pass the 'this' pointer
> explicitly into a function and cast it (see my essay on callbacks on my MVP Tips site),
> but without that trick, you can't access a member variable because there is no object
> involved.

the biggest problem is that the follwing c function is in 3rd party c
library form and i have no access right to the source code :(

cvcamSetProperty(0, CVCAM_PROP_CALLBACK, CPicture::callback);

and i can only have one parameter in callback function.

ya, btw, i try to narrow down the problem by using
ASSERT_KINDOF(CXFaceRecognitionDlg, m_pThis->GetParent() ). i realize
that m_pThis->GetParent() is not returing the correct class type. but
m_pThis->GetParent() still can access to the member function of
CXFaceRecognitionDlg.

here they go:
-------------------------------------------------------------------------------

i have the following classes:
CXFaceRecognitionDlg - main dialog class and with a CPicture control  
CPicture - control derived from CStatic

in CXFaceRecognitionDlg.h
-------------------------
class CXFaceRecognitionDlg : public CDialog
{
public:
        int GetDummy(){ return dummy; }
        void ShowDummy();

        // Dialog Data
        //{{AFX_DATA(CXFaceRecognitionDlg)
        enum { IDD = IDD_XFACERECOGNITION_DIALOG };
        CPicture        m_Picture;
protected:
        int dummy;
-------------------------

in CXFaceRecognitionDlg.cpp
---------------------------
BOOL CXFaceRecognitionDlg::OnInitDialog()
{
        // this is the c library
        // this callback will process every seconds
        cvcamSetProperty(0, CVCAM_PROP_CALLBACK, CPicture::callback);

        // explicitly set to 108
        dummy = 108;

Quote:
}

void CXFaceRecognitionDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CXFaceRecognitionDlg)
        DDX_Control(pDX, IDC_PICTURE, m_Picture);
        //}}AFX_DATA_MAP

Quote:
}

void CXFaceRecognitionDlg::ShowDummy()
{
        CString s;
        s.Format("%i", dummy);
        MessageBox(s, s, MB_OK);
Quote:
}

---------------------------

in CPicture.h
-------------
class CPicture : public CStatic
{
// Construction
public:
        static void callback(IplImage* image);
protected:      
        static CPicture* m_pThis;
-------------

in CPicture.cpp
---------------
CFaceDetectionManager* CPicture::m_spFaceDetectionManager = NULL;

CPicture::CPicture()
{      
        // I NEED THIS TO ENABLE ME TO ACCESS MEMBER FUNCTION THROUGH STATIC
FUNCTION
        m_pThis = this;

Quote:
}

void CPicture::OnLButtonDown(UINT nFlags, CPoint point)
{
        // YAHOO! I GET 108 DISPLAY
        ((CXFaceRecognitionDlg*)GetParent())->ShowDummy();

Quote:
}

// PLEASE NOTE THAT CALLBACK IS STATIC FUNCTION
void CPicture::callback(IplImage* image)
{
        // WILL GET COMPILATION ERROR FOR THE FOLLOWING CODE
        // 'CWnd::GetParent' : illegal call of non-static member function
        //
        // ((CXFaceRecognitionDlg*)GetParent())->ShowDummy();
        //

        // BUT VALUE 0 IS DISPLAYED :(  
        ((CXFaceRecognitionDlg*)(m_pThis->GetParent()))->ShowDummy();

Quote:
}

---------------

I try to debug the application by inserting
ASSERT_KINDOF(CXFaceRecognitionDlg, GetParent()); in
CPicture::OnLButtonDown
ASSERT_KINDOF(CXFaceRecognitionDlg, m_pThis->GetParent() ); in
CPicture::callback

note that ASSERT_KINDOF(CXFaceRecognitionDlg, m_pThis->GetParent() );
in CPicture::callback will

fail!!!

(1) why m_pThis->GetParent() is not class type of CXFaceRecognitionDlg
but can have a access to

function ShowDummy?

(2) how can i avoid that failure at the same time mantaining callback
as static and able to

access instance member variable?

thank you.

regards
yccheok



Mon, 28 Nov 2005 12:18:02 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. static function access member variable and member function

2. Giving static member functions access to protected functions

3. Error trying to access a derived member function from the base class

4. Order of static member func execution before main()

5. Accessing non-static functions from a static function

6. Strange member function naming problem...

7. Weirdness - callback func, class member func

8. Weirdness - callback func, class member func

9. pointer function for class member func

10. CALLBACK and non-static member function problem!

11. One Problem in Calling Static function from Non static function

12. Private member access in a different function member

 

 
Powered by phpBB® Forum Software