C++ Pointer Function binding Question

I created a small example of the problem I encountered. I've been dealing with this problem for a few days. i have not found a solution yet. I want to work with multiple instances of the Cla1 class here. therefore, I cannot define static hap_object_init and read_Data functions. thank you in advance

callback.hap_object_init = hap_object_init; // how to bind this function

callback.hap_object_init(reinterpret_cast(ref_val));

hap_characteristic characteristicCallback{};

characteristicCallback.read = read_Data; // how to bind this function with return value

hap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#ifndef _HAP_H_
    #define _HAP_H_

    #ifdef __cplusplus
    extern "C" {
    #endif

    #include <stdint.h>
    #include <stdbool.h>




    struct hap_characteristic {
        enum hap_characteristic_type type;

        void* (*read)(void* arg);

    };

    typedef struct {
        void (*hap_object_init)(void* arg);
    } hap_accessory_callback_t;



    inline void* hap_accessory_register(char* name, char* id, char* pincode, char* vendor,
                                        enum hap_accessory_category category,
                                        int port, uint32_t config_number, void* callback_arg,
                                        hap_accessory_callback_t* callback)
    {
    }

    #ifdef __cplusplus
    }
    #endif

    #endif //#ifndef _HAP_H_ 





CMakeProject1.h


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once

    #include <iostream>

    namespace NameSpa1
    {
        class Cla1
        {
        public:
            void init();
            void* read_Data(void* arg);
            void hap_object_init(void * arg);

            int ref_val = 100;
            int mux = 2;
        };

    }






CMakeProject1.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
   #include "CMakeProject1.h"
#include "hap.h"
#include <functional>

using namespace std;

int main()
{
    cout << "Hello CMake." << endl;

    auto claInstance = new NameSpa1::Cla1();
    claInstance->init();


    auto claInstance2 = new NameSpa1::Cla1();
    claInstance2->init();

    system("pause");
    return 0;
}



void NameSpa1::Cla1::init()
{

    hap_accessory_callback_t callback;

    // how to bind this function
    callback.hap_object_init = hap_object_init;

    callback.hap_object_init(reinterpret_cast<void*>(ref_val));


    hap_characteristic characteristicCallback{};

    // how to bind this function with return value
    characteristicCallback.read = read_Data;

    ref_val = reinterpret_cast<int>(characteristicCallback.read(reinterpret_cast<void*>(ref_val)));

}


void * NameSpa1::Cla1::read_Data(void *arg)
{
    cout << "Read Data Worked" << endl;

    const auto val = reinterpret_cast<int>(arg) * mux;
    return reinterpret_cast<void*>(val);
}


void NameSpa1::Cla1::hap_object_init(void* arg)
{
    cout << "Hap Init Worked" << endl;
}
Last edited on
I'm not sure what you are looking for. It could be this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

namespace NameSpa1
{
    class Cla1
    {
    public:
        void* read_Data(void* arg);
    };
}

void* NameSpa1::Cla1::read_Data(void*)
{
    std::cout << "read_Data\n";
    return nullptr;
}

int main()
{
    void*(NameSpa1::Cla1::*read)(void*) = &NameSpa1::Cla1::read_Data;

    NameSpa1::Cla1 cla;
    (cla.*read)(nullptr);
}

Or it could be this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

namespace NameSpa1
{
    class Cla1
    {
    public:
        void* (*read_Data)(void*);
    };
}

void* read_Data(void*)
{
    std::cout << "read_Data\n";
    return nullptr;
}

int main()
{
    NameSpa1::Cla1 cla;
    cla.read_Data = read_Data;
    cla.read_Data(nullptr);
}

hi

hap.h // i can't change this is library.

i want to instance cla1 but binding error like this:

callback.hap_object_init = hap_object_init; // how to bind this function // gives error like this -> "Reference to non-static member function must be called"

but if i set as static hap_object_init everythings ok but i don't want static. i want be able multiple istance this class..


here is the sample project with binding error
https://mega.nz/#!aCoFwA6Q!IbqfrW5qmpxHwQmKB8YWp_rpuXEpTpHGOjWe8Zo3Pzk
Last edited on
1
2
3
4
5
6
class foo{
public:
   return_type bar(parameters...);
}
//equivalent to
return_type bar(foo *this, parameters...);
that's the meaning of the error.


> I want to work with multiple instances of the Cla1 class here. therefore, I
> cannot define static hap_object_init and read_Data functions
that's the purpose of the argument
1
2
3
4
void* read_Data(void *arg){ //not a member function
	Cla1 *obj = reinterpret_cast<Cla1*>(arg);
	return obj->read_Data();
}
I created a small sample of the problem. How to assign this delegate function. !!must be non-static!! thank in advance

screenshot
https://ibb.co/gFnv47N


and yo can download cmake solution from this link: https://mega.nz/#!iCAWSA7J!y7Fb3SQb4At8EmfKY1c0TMD9oslScfe2dGULgGHpLmM

i want be able multiple istance this class..
So how do you want to organize these multiple instances? There must be container for this objects.

You cannot bind a member function to a pointer that requires a free function when using raw pointers. However nothing stops you from wrapping the desired class objects in static functions. So you have an indirect call. Still you need to organize the objects...
> !!must be non-static!!
OK, so how are you supposed to 'magic' a this pointer out of thin air?

Read ne555's post again.

If you're making more than 1 instance of NameSpa1::Cla1 at once, then you hap_ things need to store some kind of array / vector / list of all the live instances, from which meaningful 'this' pointers can be reconstructed using the static method wrapper previously illustrated.
wow. thank you ne555. in understand now. thank so much
@ne555
ok.I could compile but gave read access violation error:

https://i.ibb.co/GQbLMRc/Screen-Shot-2019-04-02-at-15-20-32.png
Last edited on
Something like this perhaps.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
$ cat CMakeProject1.cpp
#include <iostream>
using namespace std;

namespace NameSpa1
{
    class Cla1
    {
    public:
        void init();
        void* read_Data(void* arg);
        static void* read_data_static_single_instance(void* arg);

        int ref_val = 100;//must be non-satic field
        int mux = 2;  //must be non-satic field
    };

}

struct hap_characteristic {
    void* (*read)(void* arg);
    void *instance;             // You need this to make a 'this' pointer later
};

hap_characteristic  hap_table[10];  // this many, should be vector, list, ...
int                 hap_tableLen = 0;

void addToHap( void*(*fn)(void*), void* instance) {
    hap_table[hap_tableLen].read = fn;
    hap_table[hap_tableLen].instance = instance;
    hap_tableLen++;
}
void callHaps() {
    for ( int i = 0 ; i < hap_tableLen ; i++ ) {
        hap_table[i].read(hap_table[i].instance);
    }
}

int main()
{
    cout << "Hello CMake." << endl;
    auto claInstance = new NameSpa1::Cla1();
    claInstance->init();
    auto claInstance2 = new NameSpa1::Cla1();
    claInstance2->init();
    auto claInstance3 = new NameSpa1::Cla1();
    claInstance3->init();
    callHaps();
    cout << "Bye CMake." << endl;
    return 0;
}

void NameSpa1::Cla1::init()
{
    // Register this instance with hap
    // For classes, you need a static member function, and a copy of the 'this' pointer.
    addToHap(read_data_static_single_instance,this);
}

void* NameSpa1::Cla1::read_Data(void *arg)
{
    cout << "Called read_Data("<<arg<<")" << endl;
    cout << "this=" << reinterpret_cast<void*>(this) << endl;
    cout << "ref_val=" << ref_val << ", mux=" << mux << endl;
    return nullptr;
}

void* NameSpa1::Cla1::read_data_static_single_instance(void *arg)
{
    NameSpa1::Cla1 *thisp = reinterpret_cast<NameSpa1::Cla1 *>(arg);
    return thisp->read_Data(arg);  // arg is redundant, as it's the same as this
}
$ g++ -std=c++11 CMakeProject1.cpp 
$ ./a.out 
Hello CMake.
Called read_Data(0x1a8e030)
this=0x1a8e030
ref_val=100, mux=2
Called read_Data(0x1a8e050)
this=0x1a8e050
ref_val=100, mux=2
Called read_Data(0x1a8e070)
this=0x1a8e070
ref_val=100, mux=2
Bye CMake.
Topic archived. No new replies allowed.