从静态成员函数调用成员函数指针

问题描述 投票:0回答:0

我正在编写一个使用 SDL_Audio 并动态产生声音的程序,但我发现我的实现不是非常敏感,延迟从 .3 到 .5 秒不等。

我怀疑我在声卡需要数据之前很久就发出了声音。我的解决方案是在第一次请求音频时触发声音产生。为此,我添加了一个函数指针,该指针最初设置为一个素数函数

  • 触发发声
  • 将函数指针重置为 audioCallback 方法
  • 直接调用audioCallback方法

所以本质上我有一个静态成员函数通过成员函数指针调用成员函数,我遇到了编译问题。

寻找通过函数指针调用成员函数的正确语法。

我有以下重现我的问题的测试程序。

/*
 * testcallback.cpp
 *
 *  Created on: Apr 20, 2023
 *      Author: phil
 */
#include <SDL2/SDL.h>
#include <fstream>
#include <iostream>

class AudioCallbackTest
{
public:
    AudioCallbackTest()
    {
    SDL_Init(SDL_INIT_AUDIO);
    SDL_AudioSpec desiredSpec = {0};
    desiredSpec.format = AUDIO_S16SYS;
    desiredSpec.channels = 1;
    desiredSpec.freq = 44100;
    desiredSpec.samples = 256;
    desiredSpec.callback = audioCallbackWrap;
    desiredSpec.userdata = this;

    m_hwDevice = SDL_OpenAudioDevice(nullptr, false, &desiredSpec, NULL, 0);
    if (m_hwDevice == 0)
    {
        std::cout << "SDL_OpenAudioDevice failed: SDL error [" << SDL_GetError() << "]" << std::endl;
        return;
        }
    }

    static void audioCallbackWrap(void *_instance, Uint8* _stream, int _length)
    {
//      ((AudioCallbackTest*)_instance)->m_audioCallback(_stream, _length);
        
        ((AudioCallbackTest*)_instance)->*m_audioCallback(_stream, _length);
    }
    void audioCallback(Uint8* stream, int len)
    {
        std::cout << "audio callback" << std::endl;
    }
    void primeAudioCallback(Uint8* stream, int len)
    {
        std::cout << "prime callback" << std::endl;
        m_audioCallback = &AudioCallbackTest::audioCallback;
    }

private:
    SDL_AudioDeviceID m_hwDevice;
    void (AudioCallbackTest::*m_audioCallback)(uint8_t *stream, int len) = &AudioCallbackTest::primeAudioCallback;
};

注意静态函数中的注释行。在第一种形式中我得到了错误

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o testcallback.o ../testcallback.cpp 
../testcallback.cpp: In static member function ‘static void AudioCallbackTest::audioCallbackWrap(void*, Uint8*, int)’:
../testcallback.cpp:35:65: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((AudioCallbackTest*)_instance)->AudioCallbackTest::m_audioCallback (...)’, e.g. ‘(... ->* ((AudioCallbackTest*)_instance)->AudioCallbackTest::m_audioCallback) (...)’
   35 |                 ((AudioCallbackTest*)_instance)->m_audioCallback(_stream, _length);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~

使用第二种形式我得到以下错误

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o testcallback.o ../testcallback.cpp 
../testcallback.cpp: In static member function ‘static void AudioCallbackTest::audioCallbackWrap(void*, Uint8*, int)’:
../testcallback.cpp:37:51: error: invalid use of member ‘AudioCallbackTest::m_audioCallback’ in static member function
   37 |                 ((AudioCallbackTest*)_instance)->*m_audioCallback(_stream, _length);
      |                                                   ^~~~~~~~~~~~~~~
../testcallback.cpp:51:35: note: declared here
   51 |         void (AudioCallbackTest::*m_audioCallback)(uint8_t *stream, int len) = &AudioCallbackTest::primeAudioCallback;
      |                                   ^~~~~~~~~~~~~~~

编译器版本为GNU C++17 (Ubuntu 11.3.0-1ubuntu1~22.04) version 11.3.0 (x86_64-linux-gnu) IDE 版本:2023-03 (4.27.0) CDT 是版本:11.1.0.202212091724

我尝试过各种语法

    This->m_audioCallback(_stream, _length);
    This->*m_audioCallback(_stream, _length);
    (This->*m_audioCallback)(_stream, _length);
    This->*m_audioCallback(_stream, _length);
    (*This).*m_audioCallback(_stream, _length);

我用谷歌搜索了错误信息。

我在谷歌上搜索了“通过成员函数指针调用成员的静态成员”,找到了关于如何调用成员函数和大量函数指针示例的搜索结果,但没有一个符合要求。

我假设有一个正确的语法。

c++ function pointers static member
© www.soinside.com 2019 - 2024. All rights reserved.