Funkcja zwrotna – błędy kompilacji

2017-06-22 20:01

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

Witam Serdecznie. Używam zewnętrznej biblioteki i mam problem z jedną funkcją
Budowa funkcji z biblioteki:

DLLEXPORT  ResultCode __stdcall SetCallbackStatus(void ( *ptr)( int ) );

Jeśli zrobię tak wszystko działa:

void wyswietl_1(int liczba)
{
ShowMessage("Wyswietl_1");
}

int odp=ClientW::SetCallbackStatus(wyswietl_1);

Ale jeśli zrobię tak to dostaję błędy:

class User
{
   public:
   void wyswietl_1(int liczba)
   {
   ShowMessage("Wyswietl_1");
   }
};

User *a=new User();
int odp=ClientW::SetCallbackStatus(a->wyswietl_1);
[C++ Error] Unit1.cpp(47): E2034 Cannot convert 'void (* (_closure )(int))(int)' to 'void (*)(int)'
[C++ Error] Unit1.cpp(47): E2342 Type mismatch in parameter 'ptr' (wanted 'void (*)(int)', got 'void')
edytowany 2x, ostatnio: furious programming, 2017-06-23 14:30

Pozostało 580 znaków

kq
2017-06-22 20:05
kq
Moderator C/C++

Rejestracja: 6 lat temu

Ostatnio: 1 minuta temu

Lokalizacja: Szczecin

1

Wskaźnik na wolną funkcję i wskaźnik na element klasy to zupełnie różne rzeczy. Koncepcyjnie, możesz sobie wyobrazić, że wszystkie niestatyczne funkcje w klasie mają dodatkowy ukryty parametr - wskaźnik this. Wobec tego próbujesz przekazać funkcję przyjmującą dwa parametry jako funkcję, która przyjmuje jeden - i z tym jest problem.

Ponadto w poprzednim temacie dostał​eś już informację, że taki sposób pobrania adresu funkcji klasy jest nielegalny.

Jeśli twój callback nie ma wersji ze stanem (często nazywanym context) to czystej/łatwej metody na poprawę stanu rzeczy nie ma.


Pozostało 580 znaków

2017-06-22 20:16

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

Nie mam wersji context. Chciałem użyć klasy by w przyszłości łatwiej było modyfikować kod programu. A mógłbyś jeśli nie sprawi problemu przykład z użyciem klas bo na tym mi zależy.

Pozostało 580 znaków

2017-06-23 10:22

Rejestracja: 14 lat temu

Ostatnio: 18 godzin temu

0

Możesz zrobić tak:

struct ICallbackStatus
{
    virtual void __stdcall Invoke(int) = 0;
};

DLLEXPORT  ResultCode __stdcall SetCallbackStatus( ICallbackStatus* );

...

class User : public ICallbackStatus
{
public:

    virtual void __stdcall Invoke(int) 
    {
        ShowMessage("Wyswietl_1");
    }
};

...

User *a = new User;
int odp = ClientW::SetCallbackStatus(a);
edytowany 1x, ostatnio: _0x666_, 2017-06-23 10:27
w 64-bitowym kodzie BUM ;​) - kq 2017-06-23 10:25
A co tu bitowość ma do rzeczy? - _0x666_ 2017-06-23 10:26
To, że funkcja SetCallbackStatus z deklaracji OPa przekazuje int, a na wszystkich popularnych 64-bitowych platformach int ma 32 bity. - kq 2017-06-23 10:27
W moim przykładzie przekazuje wskaźnik ICallbackStatus* - _0x666_ 2017-06-23 10:29

Pozostało 580 znaków

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0