Zeiger auf Member Funktion in MFC Anwendung



  • Bessere Frage: Warum postest du kein (bis auf den Fehler) kompilierbares Minimalpeispiel wie in Den richtigen Code posten gefordert?

    Würde dann ca. so aussehen:

    #include <cstdint>
    
    typedef void * freenect_device;
    typedef void( *freenect_depth_cb )( freenect_device *dev, void *depth, uint32_t timestamp );
    
    void freenect_set_depth_callback (freenect_device *dev, freenect_depth_cb cb ) {}
    
    struct foo_t
    {
    	void depth_cb(freenect_device* dev, void* depth, uint32_t timestamp);
    	void bar();
    };
    
    void foo_t::depth_cb(freenect_device* dev, void* depth, uint32_t timestamp) {}
    
    void foo_t::bar()
    {
    	freenect_device * f_dev;
    
    	freenect_set_depth_callback( f_dev, depth_cb );
    }
    
    int main() {}
    

    Fehler:

    Zeile 20: 'foo_t::depth_cb': function call missing argument list; use '&foo_t::depth_cb' to create a pointer to member
    

    Dann würdest du mit Antworten überhäuft. Gefallen würden sie dir aber nicht.



  • also ich habe ein programm in Win32 console geschrieben und das hatte alles funktioniert.... und den wollte ich jetzt mit Mfc anwendung schreiben, mit Picture Control und Button ...

    als das das Original(win32 console) Code Sieht so aus:

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
     #include <assert.h>
    #include <libfreenect.h>
    #include <pthread.h>
    #include<iostream>
    #define CV_NO_BACKWARD_COMPATIBILITY
    #include "opencv2\opencv.hpp"
    //#include <opencv/cv.h>
    #include <opencv/highgui.h>
    #include <opencv2\imgproc\imgproc.hpp>
    #include <opencv2\core\core.hpp>
    #include <vector>
    
    #define FREENECTOPENCV_WINDOW_D "Depthimage"
    //#define FREENECTOPENCV_WINDOW_N "Normalimage"
    #define FREENECTOPENCV_RGB_DEPTH 3
    #define FREENECTOPENCV_DEPTH_DEPTH 1
    #define FREENECTOPENCV_RGB_WIDTH 640
    #define FREENECTOPENCV_RGB_HEIGHT 480
    #define FREENECTOPENCV_DEPTH_WIDTH 640
    #define FREENECTOPENCV_DEPTH_HEIGHT 480
    using namespace cv ;
    IplImage* depthimg = 0;
    
    IplImage* tempimg = 0;
    
    IplImage* canny_temp= 0;
    
    	pthread_mutex_t mutex_depth = PTHREAD_MUTEX_INITIALIZER;
    
    	pthread_t cv_thread;
    
    // , called by libfreenect
    void depth_cb(freenect_device *dev, void *depth, uint32_t timestamp)
    
    {
            cv::Mat depth8;
            cv::Mat mydepth = cv::Mat( FREENECTOPENCV_DEPTH_WIDTH,FREENECTOPENCV_DEPTH_HEIGHT,CV_16UC1, depth);
    
        mydepth.convertTo(depth8, CV_8UC1, 1.0/4.0);
    		//mydepth.convertTo(depth8, CV_8UC1,155.0/2048.0);
    		 //mydepth.convertTo(depth8, CV_16UC1, 255.0/2048.0);
            pthread_mutex_lock( &mutex_depth );
            memcpy(depthimg->imageData, depth8.data, 640*480);
            // unlock mutex
            pthread_mutex_unlock( &mutex_depth );
    
    }
    
    void *cv_threadfunc (void *ptr) {
            cvNamedWindow( FREENECTOPENCV_WINDOW_D, CV_WINDOW_AUTOSIZE );
    
            cvNamedWindow( "Depth Canny ", CV_WINDOW_AUTOSIZE );
    		//cvNamedWindow (" gauss ", CV_WINDOW_AUTOSIZE ) ;
    
            depthimg = cvCreateImage(cvSize(FREENECTOPENCV_DEPTH_WIDTH, FREENECTOPENCV_DEPTH_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_DEPTH_DEPTH);
    
          tempimg = cvCreateImage(cvSize(FREENECTOPENCV_RGB_WIDTH, FREENECTOPENCV_RGB_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_RGB_DEPTH);
    
            canny_temp = cvCreateImage(cvSize(FREENECTOPENCV_DEPTH_WIDTH, FREENECTOPENCV_DEPTH_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_DEPTH_DEPTH);
    		//gaussimg=cvCreateImage(cvSize(FREENECTOPENCV_DEPTH_WIDTH, FREENECTOPENCV_DEPTH_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_DEPTH_DEPTH);
    
            while (1) {
                    //lock mutex 
                    pthread_mutex_lock( &mutex_depth );
    
                    // bild fenster
                   cvCanny(depthimg, canny_temp, 200.0, 50.0,3);
    
                     cvCvtColor(depthimg,tempimg,CV_GRAY2BGR);
                    cvCvtColor(tempimg,tempimg,CV_HSV2BGR);
    				//cvCvtColor(gaussimg,tempimg,CV_GAUSSIAN);
                    cvShowImage(FREENECTOPENCV_WINDOW_D,tempimg);
                    cvShowImage("Depth Canny Gauss", canny_temp);
    
                    pthread_mutex_unlock( &mutex_depth );
    
                    if( cvWaitKey( 15 )==27 )
                                    break;
    
            }
    		cvReleaseImage( &depthimg );
    		cvReleaseImage( &tempimg );
    	//	cvReleaseImage(&gaussimg);
            pthread_exit(NULL);
    
            return NULL;
    
    }
    
    int main(int argc, char **argv)
    {
    
      freenect_context *f_ctx;
            freenect_device *f_dev;
    
            int res = 0;
            int die = 0;
            printf("Kinect camera test\n");
    
                    pthread_mutex_unlock( &mutex_depth );
    
            if (freenect_init(&f_ctx, NULL) < 0) {
                            printf("freenect_init() failed\n");
                            return 1;
                    }
    
                    if (freenect_open_device(f_ctx, &f_dev, 0) < 0) {
                            printf("Could not open device\n");
                            return 1;
                    }
    
            freenect_set_depth_callback(f_dev, depth_cb);
    
            //  opencv display thread  erstellen
            res = pthread_create(&cv_thread, NULL, cv_threadfunc, (void*) depthimg);
            if (res) {
                    printf("pthread_create failed\n");
                    return 1;
            }
    
            printf("init done\n");
    
            freenect_start_depth(f_dev);
    
            while(!die && freenect_process_events(f_ctx) >= 0 );
    
    }
    

    und was ich in MFC versucht habe sieht so aus

    #include "stdafx.h"
    #include "MFC.FREENECT.h"
    #include "MFC.FREENECTDlg.h"
    #include "afxdialogex.h"
    #include "libfreenect.h"
    #include"libfreenect.hpp"
    #include"pthread.h"
    #include"opencv\cv.h"
    #include "opencv2\opencv.hpp"
    
    #include <opencv/highgui.h>
    #include <opencv2\imgproc\imgproc.hpp>
    #include <opencv2\core\core.hpp>
    #define FREENECTOPENCV_RGB_DEPTH 3
    #define FREENECTOPENCV_DEPTH_DEPTH 1
    #define FREENECTOPENCV_RGB_WIDTH 640
    #define FREENECTOPENCV_RGB_HEIGHT 480
    #define FREENECTOPENCV_DEPTH_WIDTH 640
    #define FREENECTOPENCV_DEPTH_HEIGHT 480
    pthread_mutex_t mutex_depth = PTHREAD_MUTEX_INITIALIZER;
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    // CAboutDlg-Dialogfeld für Anwendungsbefehl "Info"
    
    class CAboutDlg : public CDialogEx
    {
    public:
    	CAboutDlg();
    
    // Dialogfelddaten
    	enum { IDD = IDD_ABOUTBOX };
    
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV-Unterstützung
    
    // Implementierung
    protected:
    	DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
    END_MESSAGE_MAP()
    
    // CMFCFREENECTDlg-Dialogfeld
    
    CMFCFREENECTDlg::CMFCFREENECTDlg(CWnd* pParent /*=NULL*/)
    	: CDialogEx(CMFCFREENECTDlg::IDD, pParent)
    
    , m_depth_video(NULL)
    {
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CMFCFREENECTDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialogEx::DoDataExchange(pDX);
    
    	DDX_Control(pDX, IDC_STATIC_DEPTH, m_depth);
    }
    
    BEGIN_MESSAGE_MAP(CMFCFREENECTDlg, CDialogEx)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    
    	ON_WM_TIMER()
    	ON_BN_CLICKED(IDC_BTN_BUTTON, &CMFCFREENECTDlg::OnBnClickedBtnButton)
    END_MESSAGE_MAP()
    
    // CMFCFREENECTDlg-Meldungshandler
    
    BOOL CMFCFREENECTDlg::OnInitDialog()
    {
    	CDialogEx::OnInitDialog();
    
    	// Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
    	// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		BOOL bNameValid;
    		CString strAboutMenu;
    		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
    		ASSERT(bNameValid);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden
    	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden
    
    	// TODO: Hier zusätzliche Initialisierung einfügen
    	pDC2 = m_depth.GetDC();
        m_depth.GetClientRect(&rect2);
    
    	return TRUE;  // TRUE zurückgeben, wenn der Fokus nicht auf ein Steuerelement gesetzt wird
    }
    
    void CMFCFREENECTDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    	{
    		CAboutDlg dlgAbout;
    		dlgAbout.DoModal();
    	}
    	else
    	{
    		CDialogEx::OnSysCommand(nID, lParam);
    	}
    }
    
    // Wenn Sie dem Dialogfeld eine Schaltfläche "Minimieren" hinzufügen, benötigen Sie
    //  den nachstehenden Code, um das Symbol zu zeichnen. Für MFC-Anwendungen, die das 
    //  Dokument/Ansicht-Modell verwenden, wird dies automatisch ausgeführt.
    
    void CMFCFREENECTDlg::OnPaint()
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // Gerätekontext zum Zeichnen
    
    		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
    		// Symbol in Clientrechteck zentrieren
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Symbol zeichnen
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialogEx::OnPaint();
    		CDialog::UpdateWindow();
    
    	}
    }
    
    // Die System ruft diese Funktion auf, um den Cursor abzufragen, der angezeigt wird, während der Benutzer
    //  das minimierte Fenster mit der Maus zieht.
    HCURSOR CMFCFREENECTDlg::OnQueryDragIcon()
    {
    	return static_cast<HCURSOR>(m_hIcon);
    }
    
    void CMFCFREENECTDlg::depth_cb(freenect_device* dev, void* depth, uint32_t timestamp)
    {
    
            cv::Mat depth8;
            cv::Mat mydepth = cv::Mat( FREENECTOPENCV_DEPTH_WIDTH,FREENECTOPENCV_DEPTH_HEIGHT,CV_16UC1, depth);
            mydepth.convertTo(depth8, CV_8UC1, 1.0/4.0);
            pthread_mutex_lock( &mutex_depth );
    		memcpy(m_depth_video->imageData, depth8.data, 640*480);
    
            pthread_mutex_unlock( &mutex_depth );
    
    }
    
    void CMFCFREENECTDlg::cvShowImage(IplImage* img, UINT ID)
    {
    	CDC* pDC = GetDlgItem(ID)->GetDC(); //get the dc of the ID
    HDC hDC = pDC->GetSafeHdc();
    CRect rect;
    GetDlgItem(ID)->GetClientRect(rect);
    int rectWidth = rect.right - rect.left; //get the width and height of the rectangle
    int rectHeight = rect.bottom - rect.top;
    int imgWidth = img->width; //get the width and height of the image
    int imgHeight = img->height;
    int Width = (int)(rectWidth - imgWidth) / 2; //make the image show in the middle of the picture control
    int Height = (int)(rectHeight - imgHeight) / 2;
    SetRect(rect, Width, Height, Width + imgWidth, Height + imgHeight);
     CvvImage cimg;
    cimg.CopyOf(img);
    cimg.DrawToHDC(hDC, &rect); //show the cimg by hDC
    ReleaseDC(pDC);
    
    }
    
    void CMFCFREENECTDlg::cv_threadfunc(void* ptr)
    {
    	IplImage* tempimg =0 ;
    
            m_depth_video= cvCreateImage(cvSize(FREENECTOPENCV_DEPTH_WIDTH, FREENECTOPENCV_DEPTH_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_DEPTH_DEPTH);
    
           tempimg = cvCreateImage(cvSize(FREENECTOPENCV_RGB_WIDTH, FREENECTOPENCV_RGB_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_RGB_DEPTH);
    
           while(1) {
                    //lock mutex 
                    pthread_mutex_lock( &mutex_depth );
    
                    // bild fenster
    
    				cvCvtColor(m_depth_video,tempimg,CV_GRAY2BGR);
                    cvCvtColor(tempimg,tempimg,CV_HSV2BGR);
    				//cvCvtColor(gaussimg,tempimg,CV_GAUSSIAN);
    				cvShowImage(m_depth_video ,IDC_STATIC_DEPTH);
    
                    pthread_mutex_unlock( &mutex_depth );
    
                    if( cvWaitKey( 15 )==27 )
                                    break;
    
            }
    	   cvReleaseImage( &m_depth_video);
    		//cvReleaseImage( &tempimg );
    	//	cvReleaseImage(&gaussimg);
            pthread_exit(NULL);
    
    		return ;
    }
    
    void CMFCFREENECTDlg::OnBnClickedBtnButton()
    {
    	// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
    	freenect_context *f_ctx;
            freenect_device *f_dev;
    
            int res = 0;
            int die = 0;
            printf("Kinect camera test\n");
    
                    pthread_mutex_unlock( &mutex_depth );
    
            if (freenect_init(&f_ctx, NULL) < 0) {
                            printf("freenect_init() failed\n");
                            return ;
                    }
    
                    if (freenect_open_device(f_ctx, &f_dev, 0) < 0) {
                            printf("Could not open device\n");
                            return ;
                    }
    
    				freenect_set_depth_callback(f_dev,depth_cb);
    
            //  opencv display thread  erstellen
            res = pthread_create(&cv_thread, NULL, cv_threadfunc, (void*) m_depth_video);
            if (res) {
                    printf("pthread_create failed\n");
                    return ;
            }
    
            printf("init done\n");
    
            freenect_start_depth(f_dev);
    
            while(!die && freenect_process_events(f_ctx) >= 0 );
    }
    

    Fehler zeilen sind 292 296



  • _ooOoo_
                               o8888888o
                               88"."88
                               (|-_-|)
                               O\    =    /O
                            ____/---'__.'\||//``.
                         /    \\|||    :    |||//    \
                        /    _|||||-:-|||||_    \
                        |     |\\\    -    /'||     |
                        |\_|    \`---'//`    `|_/`   `|`                     `\`    `.-\__`-.-'
    /-./___..'    /--.--\    .`   `.'___`                `.""`   `'<`.___<|>/.'>"".||:``-\.;._/;.'//    .';|
                  \    \   ``-.__._.'_/_/    -'_.'/
        ===========-.___-.
    `   \___    /__.-'_.'_.-'===========

    Ooooommmmm!



  • ?????



  • So ein langer Thread mit massenweise Metadiskussionen, wo man doch im Prinzip schon am Threadtitel sieht, was das Problem ist... manchmal liebe ich dieses Forum.

    anix: Das übergebene Callback muss ein Funktionszeiger sein. Ein Funktionszeiger kann auf eine freie Funktion oder eine statische Memberfunktion zeigen. Er kann nicht auf eine nichtstatische Memberfunktion zeigen, weil beim Aufruf dort ein versteckter Parameter, nämlich ein Zeiger auf das zugrundeliegende Objekt (this) mit übergeben wird. Bei deinem ersten Beispiel ist depth_cb eine freie Funktion, also hast du kein Problem. Bei deinem zweiten Beispiel ist es eine nichtstatische Memberfunktion. Mach daraus eine freie oder eine statische Memberfunktion. Du wirst dabei die eine oder andere Membervariable statisch machen müssen oder sonst andere Umbauten vornehmen müssen, aber so ist das nunmal. Die API die du verwendest ist anscheinend auch nicht flexibel genug, um das besser zu lösen.



  • Bashar schrieb:

    Bei deinem ersten Beispiel ist depth_cb eine freie Funktion,

    Echt, sieht man das irgendwo? Ich meine klar, man kann sich denken dass es das Problem sein wird, aber der/die/das Anix hat ja wieder die relevante Stelle unterschlagen.
    Weiters hat er/sie/es nichtmal die Fehlermeldung gepostet die der Compiler auswirft.

    Wieso sollte man da helfen wollen/sollen?



  • kannst du mir sagen oder ein tipp geben wie es geht ?
    ich habe recherchiert aber leider komme ich nicht weiter



  • hustbaer schrieb:

    Bashar schrieb:

    Bei deinem ersten Beispiel ist depth_cb eine freie Funktion,

    Echt, sieht man das irgendwo?

    Ja, da wo sie steht.

    Wieso sollte man da helfen wollen/sollen?

    Gar nicht, alles ist hier freiwillig. Ich wollte aber eigentlich nicht dazu auffordern, die Metadiskussion weiter ausufern zu lassen.

    Anix schrieb:

    kannst du mir sagen oder ein tipp geben wie es geht ?
    ich habe recherchiert aber leider komme ich nicht weiter

    Wie was genau geht? Mein Tipp war eigentlich schon deutlich ausführlicher als normalerweise nötig, wenn du den nicht umsetzen kannst, fehlt es dir massiv an Grundlagen in C++.



  • Anix schrieb:

    kannst du mir sagen oder ein tipp geben wie es geht ?
    ich habe recherchiert aber leider komme ich nicht weiter

    Kannst du lesen?



  • Bashar schrieb:

    hustbaer schrieb:

    Bashar schrieb:

    Bei deinem ersten Beispiel ist depth_cb eine freie Funktion,

    Echt, sieht man das irgendwo?

    Ja, da wo sie steht.

    Ach Mist, vor lauter schnell schnell den falschen Teil zitiert.
    Ich meine natürlich

    Bei deinem zweiten Beispiel ist es eine nichtstatische Memberfunktion.



  • Bashar schrieb:

    Wieso sollte man da helfen wollen/sollen?

    Gar nicht, alles ist hier freiwillig. Ich wollte aber eigentlich nicht dazu auffordern, die Metadiskussion weiter ausufern zu lassen.

    Mit guter Hilfe bei schlechten Fragen züchtest du mehr schlechte Fragen in der Zukunft.


Anmelden zum Antworten