wektor jako argument funkcji

0

Cześć,

Potrzebuję wywołać taką funkcję:

// HRESULT DirectOutput_SetLed(void* hDevice, DWORD dwPage, DWORD dwIndex, DWORD dwValue);
// Set the state of a LED on the device
// Parameters
//     hDevice : opaque device handle
//     dwPage : page to display the led on
//     dwIndex : index of the led
//     dwValue : value of the led (0 is off)
// returns
//     S_OK : succeeded
//     E_HANDLE : hDevice is not a valid device handle
//     E_NOTIMPL : hDevice does not have any leds
//     E_INVALIDARG : dwPage or dwIndex is not a valid id
//     E_PAGENOTACTIVE : dwPage is not the active page
HRESULT __stdcall DirectOutput_SetLed(void* hDevice, DWORD dwPage, DWORD dwIndex, DWORD dwValue);

z mojej funkcji:

void x52_output::color_led(void * hDevice, DWORD dwPage, uint8_t nr, int8_t param){
    if(nr==LED_FIRE || nr==LED_THROTTLE){
        if(param<=0){ //wylaczony
            DirectOutput_SetLed(hDevice, dwPage, nr, 0); //green
        } else {
            DirectOutput_SetLed(hDevice, dwPage, nr, 1); //green
        }
    } else {
        if(param==0){ //wylaczony
            DirectOutput_SetLed(hDevice, dwPage, nr, 1);  //red
            DirectOutput_SetLed(hDevice, dwPage, nr+1, 0); //green
        } else if (param==1){ //wlaczony
            DirectOutput_SetLed(hDevice, dwPage, nr, 0);  //red
            DirectOutput_SetLed(hDevice, dwPage, nr+1, 1); //green
        } else if (param==-1){ //diody wylaczone
            DirectOutput_SetLed(hDevice, dwPage, nr, 0);  //red
            DirectOutput_SetLed(hDevice, dwPage, nr+1, 0); //green
        }else { //stan posredni
            DirectOutput_SetLed(hDevice, dwPage, nr, 1);  //red
            DirectOutput_SetLed(hDevice, dwPage, nr+1, 1); //green
        }
    }
}

w pliku głównym wywołuję ją tak:

std::vector<void*> devices;
DWORD dwPage = 1;

x52output::color_led(devices[0], dwPage, 1, 1);

Wywołanie tej funkcji (DirectOutput_SetLed) z main działa bez problemu. Natomiast tutaj nie umiem poradzić sobie z poprawnym przekazaniem tego wektora do urządzenia. Próbowałem rozpisać to inaczej ale albo się nie kompiluje, albo nie działa, albo zawiesza program. Poradzicie coś?

0

Ale chcesz ten wektor przekazać jako C-style array (void* array[3]) czy jak bo trochę pytania nie rozumiem?
No to wtedy devices.data() (lepiej) albo &devices[0]

0

Zmień typ argumentu funkcji z

void* hDevice

na

vector<void *> & hDevArray

Tylko wewnątrz funkcji będzie trzeba to odpowiednio obsłużyć.

0

Popraw tak:

class LedException : public : std::exception {
public:
    explicit LedException(HRESULT result)
        : mResult{ result }
    {
    }
    virtual const char* what() const noexcept override
    {
        if (mDesc.empty()) {
            makeDesc();
        }
        return mDesc.c_str();
    }

private:
    void makeDesc() const
    {
        switch (mResult) {
        case E_HANDLE:
            mDesc = "hDevice is not a valid device handle";
            break;
        case E_NOTIMPL:
            mDesc = "hDevice does not have any leds";
            break;
        case E_INVALIDARG:
            mDesc = "dwPage or dwIndex is not a valid id";
            break;
        case E_PAGENOTACTIVE:
            mDesc = "dwPage is not the active page";
            break;
        default:
            mDesc = std::to_string(mResult);
        }
    }

private:
    mutable std::string mDesc;
    HRESULT mResult;
};

void checkForErrors(HRESULT result)
{
     if (result == S_OK) return;
     throw LedException{result};
}

void x52_output::color_led(void * hDevice, DWORD dwPage, uint8_t nr, int8_t param){
    if(nr==LED_FIRE || nr==LED_THROTTLE){
        if(param<=0){ //wylaczony
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr, 0)); //green
        } else {
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr, 1)); //green
        }
    } else {
        if(param==0){ //wylaczony
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr, 1));  //red
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr+1, 0)); //green
        } else if (param==1){ //wlaczony
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr, 0));  //red
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr+1, 1)); //green
        } else if (param==-1){ //diody wylaczone
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr, 0));  //red
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr+1, 0)); //green
        }else { //stan posredni
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr, 1));  //red
            checkForErrors(DirectOutput_SetLed(hDevice, dwPage, nr+1, 1)); //green
        }
    }
}

Uruchom i potem opisz co się dzieje.

0

BTW jeszcze lepiej jakby to wyglądało tak:

class LedException : public : std::exception {
public:
    explicit LedException(HRESULT result)
        : mResult{ result }
    {
    }
    virtual const char* what() const noexcept override
    {
        if (mDesc.empty()) {
            makeDesc();
        }
        return mDesc.c_str();
    }

private:
    void makeDesc()
    {
        switch (mResult) {
        case E_HANDLE:
            mDesc = "hDevice is not a valid device handle";
            break;
        case E_NOTIMPL:
            mDesc = "hDevice does not have any leds";
            break;
        case E_INVALIDARG:
            mDesc = "dwPage or dwIndex is not a valid id";
            break;
        case E_PAGENOTACTIVE:
            mDesc = "dwPage is not the active page";
            break;
        default:
            mDesc = std::to_string(mResult);
        }
    }

private:
    mutable std::string mDesc;
    HRESULT mResult;
};

class ILedDevice {
public:
    virtual ~ILedDevice() {}
    virtual void SetLed(DWORD dwPage, DWORD dwIndex, DWORD dwValue) = 0;
};

class LedDevice : public ILedDevice final {
public:
    ~LedDevice();

    LedDevice( ...... ) {
         mDevice = ......;
    }

    static void checkForErrors(HRESULT result) const
    {
        if (result == S_OK) return;
        throw LedException{result};
    }

    void SetLed(DWORD dwPage, DWORD dwIndex, DWORD dwValue) override
    {
        checkForErrors(DirectOutput_SetLed(mDevice, dwPage, dwIndex, dwValue));
    }

private:
    void* mDevice;
};

...
// pole w klasie x52_output
// ILedDevice* mLed;
void x52_output::color_led(void * hDevice, DWORD dwPage, uint8_t nr, int8_t param){
    if(nr==LED_FIRE || nr==LED_THROTTLE){
        if(param<=0){ //wylaczony
            mLed->SetLed(dwPage, nr, 0); //green
        } else {
            mLed->SetLed(dwPage, nr, 1); //green
        }
    } else {
        if(param==0){ //wylaczony
            mLed->SetLed(dwPage, nr, 1);  //red
            mLed->SetLed(dwPage, nr+1, 0); //green
        } else if (param==1){ //wlaczony
            mLed->SetLed(dwPage, nr, 0);  //red
            mLed->SetLed(dwPage, nr+1, 1); //green
        } else if (param==-1){ //diody wylaczone
            mLed->SetLed(dwPage, nr, 0);  //red
            mLed->SetLed(dwPage, nr+1, 0); //green
        }else { //stan posredni
            mLed->SetLed(dwPage, nr, 1);  //red
            mLed->SetLed(dwPage, nr+1, 1); //green
        }
    }
}
0

Nie wiem czy podołam. Wklejone. Niestety nie kompiluje się

21:13:43: Uruchamianie kroków budowania dla projektu MSFS_X52...
21:13:43: Konfiguracja niezmieniona, krok qmake pominięty.
21:13:43: Uruchamianie "D:\Qt\Tools\mingw730_64\bin\mingw32-make.exe" -j12
D:/Qt/Tools/mingw730_64/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'C:/Users/jwali/Documents/Qt Projekty/build-MSFS_X52-Desktop_Qt_5_12_2_MinGW_64_bit-Debug'
g++ -c -fno-keep-inline-dllexport -g -std=gnu++11 -Wall -W -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_XML_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\MSFS_X52 -I. -I..\MSFS_X52 -ID:\Qt\5.12.2\mingw73_64\include -ID:\Qt\5.12.2\mingw73_64\include\QtWidgets -ID:\Qt\5.12.2\mingw73_64\include\QtGui -ID:\Qt\5.12.2\mingw73_64\include\QtANGLE -ID:\Qt\5.12.2\mingw73_64\include\QtXml -ID:\Qt\5.12.2\mingw73_64\include\QtCore -Idebug -I. -IC:\VulkanSDK\1.0.51.0\include -ID:\Qt\5.12.2\mingw73_64\mkspecs\win32-g++ -o debug\x52_output.o ..\MSFS_X52\x52_output.cpp
..\MSFS_X52\x52_output.cpp:124:21: warning: missing terminating " character
mDesc = "std::to_string(mResult);
^
..\MSFS_X52\x52_output.cpp:124:21: error: missing terminating " character
mDesc = "std::to_string(mResult);
^~~~~~~~~~~~~~~~~~~~~~~~~
..\MSFS_X52\x52_output.cpp:93:29: error: expected class-name before ':' token
class LedException : public : std::exception {
^
..\MSFS_X52\x52_output.cpp:93:29: error: expected '{' before ':' token
..\MSFS_X52\x52_output.cpp:93:29: error: expected unqualified-id before ':' token
..\MSFS_X52\x52_output.cpp: In function 'void checkForErrors(HRESULT)':
..\MSFS_X52\x52_output.cpp:136:31: error: too many initializers for 'LedException'
throw LedException{result};
^
..\MSFS_X52\x52_output.cpp:136:31: error: invalid use of incomplete type 'class LedException'
..\MSFS_X52\x52_output.cpp:93:7: note: forward declaration of 'class LedException'
class LedException : public : std::exception {
^~~~~~~~~~~~
mingw32-make[1]: *** [Makefile.Debug:709: debug/x52_output.o] Error 1
mingw32-make[1]: Leaving directory 'C:/Users/jwali/Documents/Qt Projekty/build-MSFS_X52-Desktop_Qt_5_12_2_MinGW_64_bit-Debug'
mingw32-make: *** [Makefile:38: debug] Error 2
21:13:45: Proces "D:\Qt\Tools\mingw730_64\bin\mingw32-make.exe" zakończył się kodem wyjściowym 2.
Błąd budowania / instalowania projektu MSFS_X52 (zestaw narzędzi: Desktop Qt 5.12.2 MinGW 64-bit)
Podczas wykonywania kroku "Make"
21:13:45: Elapsed time: 00:02.

Nie wiem czy problemem nie jest błędna inicjalizacja funkcji zwracającej urządzenie. Właśnie próbuję przetestować. Ta funkcja wygląda tak:

DirectOutput_RegisterDeviceCallback
Syntax

    HRESULT DirectOutput_RegisterDeviceCallback(Pfn_DirectOutput_Device_Callback pfnCallback, void* pvParam);

Parameters
pfnCallback
[in] A pointer to the callback function to be called whenever a device is added or removed.
pvParam
[in] An application supplied context pointer that will be passed to the callback function.
Return Values
S_OK
The call completed successfully
E_HANDLE
DirectOutput was not initialized.
Notes
Passing a NULL function pointer will disable the callback.
0

MarekR22 dzieki wielkie. Niestety sprowadziles mnie do piaskownicy ;P Juz myslalem, ze zacznam lapac o co chodzi, a tu sie okazuje, ze nie umiem uruchomic gotowego kodu, ktory od Ciebie dostalem.
Wydaje mi sie, ze problem moze lezec po stronie inicjalizacji callback'ow. Sprawdze to dzisiaj wieczorem i dam znac co mi z tego wyszlo.

Znalazłem rozwiązanie. Problemem była zła deklaracja callback'ów. Dodanie ich w pliku głównym rozwiązało problem. Niestety tylko takie rozwiązanie działa choć chciałem to ogarnąć z poziomu funkcji init w mojej bibliotece.

void __stdcall DirectOutput_Device_Callback(void* hDevice, bool bAdded, void* pvContext) {
    if (bAdded) {
        devices.push_back(hDevice);
    }
    else {

    }
}

void __stdcall DirectOutput_Enumerate_Callback(void* hDevice, void* pvContext) {
    devices.push_back(hDevice);
}

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