windows、'undefined reference' 上 FMOD 的命令行链接

Command line linking for FMOD on windows, 'undefined reference'

我知道这可能是一个相当愚蠢的问题,但经过两天的尝试,我想我还是会问的。我是 C++ 的新手,所以我认为会有一个非常简单的解决方案。

当我尝试在命令行上编译 FMOD API 的低级示例部分中的示例时,我总是遇到 FMOD 内容的“未定义引用”错误。我知道库一定有问题,但正如您在 makefile 中看到的那样,我尝试包含所有内容:

在FMOD API的lib文件夹中有:

fmod_vc.lib , fmodL_vc.lib, fmod64_vc.lib, fmodL64_vc.lib, libfmod.a, libfmodL.a

我在 Windows 8.1 64 位上使用最新版本的 FMOD API。该问题与编译器无关。我尝试了 GCC/Cygwin 和 CLANG。错误输出由 MinGW 生成。我想我在网上到处搜索。 C++:Undefined reference to 'FMOD:: X' 的答案不适合我。据我所知,API.

中不再有 fmodex_vc.lib/fmodex64_vc.lib

这是我的 makefile:

CFLAGS = -m64 -c -Wall -g --std=c++11
LFLAGS = -m64 -g -Wl,-rpath=../lib

INCLUDE_PATH = -I../inc
LIBRARY_PATH = -L../lib

LIBS = -lfmod64 -lfmodL64 -lfmod64_vc -lfmodL64_vc

all:    generate_tone.o common.o common_platform.o
    g++ $(LFLAGS) $(LIBRARY_PATH) generate_tone.o common.o common_platform.o -o generate.exe ../lib/libfmod.a ../lib/libfmodL.a $(LIBS)  

common.o:   common.cpp common.h
    g++ $(CFLAGS)  $(INCLUDE_PATH) common.cpp -o common.o

common_platform.o:  common_platform.cpp common_platform.h 
    g++ $(CFLAGS)  $(INCLUDE_PATH) common_platform.cpp -o common_platform.o

generate_tone.o:    generate_tone.cpp
    g++ $(CFLAGS) $(INCLUDE_PATH) generate_tone.cpp  -o generate_tone.o

错误信息如下:

generate_tone.o: In function `FMOD_Main()':
c:\cSandBox\fmod\examples/generate_tone.cpp:28: undefined reference to `FMOD::System::getVersion(unsigned int*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:36: undefined reference to `FMOD::System::init(int, unsigned int, void*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:42: undefined reference to `FMOD::System::createDSPByType(FMOD_DSP_TYPE, FMOD::DSP**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:44: undefined reference to `FMOD::DSP::setParameterFloat(int, float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:58: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:62: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:64: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:66: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:68: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:76: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:80: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:82: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:84: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:86: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:94: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:98: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:100: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:102: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:104: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:112: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:116: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:118: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:120: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:122: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:130: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:142: undefined reference to `FMOD::ChannelControl::getVolume(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:149: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:157: undefined reference to `FMOD::Channel::getFrequency(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:162: undefined reference to `FMOD::Channel::setFrequency(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:167: undefined reference to `FMOD::System::update()'
c:\cSandBox\fmod\examples/generate_tone.cpp:176: undefined reference to `FMOD::Channel::getFrequency(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:178: undefined reference to `FMOD::ChannelControl::getVolume(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:180: undefined reference to `FMOD::ChannelControl::isPlaying(bool*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:209: undefined reference to `FMOD::DSP::release()'
c:\cSandBox\fmod\examples/generate_tone.cpp:211: undefined reference to `FMOD::System::close()'
c:\cSandBox\fmod\examples/generate_tone.cpp:213: undefined reference to `FMOD::System::release()'
common_platform.o: In function `Common_Init(void**)':
c:\cSandBox\fmod\examples/common_platform.cpp:78: undefined reference to `__imp_CoInitializeEx'
common_platform.o: In function `Common_Close()':
c:\cSandBox\fmod\examples/common_platform.cpp:83: undefined reference to `__imp_CoUninitialize'
collect2.exe: error: ld returned 1 exit status

这是源文件:

/*==============================================================================
Generate Tone Example
Copyright (c), Firelight Technologies Pty, Ltd 2004-2017.

This example shows how to play generated tones using System::playDSP
instead of manually connecting and disconnecting DSP units.
==============================================================================*/
#include "fmod.hpp"
#include "common.h"

int FMOD_Main()
{
    FMOD::System    *system;
    FMOD::Channel   *channel = 0;
    FMOD::DSP       *dsp;
    FMOD_RESULT      result;
    unsigned int     version;
    void            *extradriverdata = 0;

    Common_Init(&extradriverdata);

    /*
        Create a System object and initialize.
    */
    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->getVersion(&version);
    ERRCHECK(result);

    if (version < FMOD_VERSION)
    {
        Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION);
    }

    result = system->init(32, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);

    /*
        Create an oscillator DSP units for the tone.
    */
    result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp);
    ERRCHECK(result);
    result = dsp->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, 440.0f); /* Musical note 'A' */
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.5f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 0);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.125f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 1);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.125f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 2);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION4))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.5f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 4);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_MORE))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
                channel = 0;
            }
        }

        if (channel)
        {
            if (Common_BtnDown(BTN_UP) || Common_BtnDown(BTN_DOWN))
            {
                float volume;

                result = channel->getVolume(&volume);
                ERRCHECK(result);

                volume += (Common_BtnDown(BTN_UP) ? +0.1f : -0.1f);
                volume = (volume > 1.0f) ? 1.0f : volume;
                volume = (volume < 0.0f) ? 0.0f : volume;

                result = channel->setVolume(volume);
                ERRCHECK(result);
            }

            if (Common_BtnDown(BTN_LEFT) || Common_BtnDown(BTN_RIGHT))
            {
                float frequency;

                result = channel->getFrequency(&frequency);
                ERRCHECK(result);

                frequency += (Common_BtnDown(BTN_RIGHT) ? +500.0f : -500.0f);

                result = channel->setFrequency(frequency);
                ERRCHECK(result);
            }
        }

        result = system->update();
        ERRCHECK(result);

        {
            float frequency = 0.0f, volume = 0.0f;
            bool playing = false;

            if (channel)
            {
                result = channel->getFrequency(&frequency);
                ERRCHECK(result);
                result = channel->getVolume(&volume);
                ERRCHECK(result);
                result = channel->isPlaying(&playing);
                ERRCHECK(result);
            }

            Common_Draw("==================================================");
            Common_Draw("Generate Tone Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2017.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to play a sine wave", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to play a square wave", Common_BtnStr(BTN_ACTION2));
            Common_Draw("Press %s to play a saw wave", Common_BtnStr(BTN_ACTION3));
            Common_Draw("Press %s to play a triangle wave", Common_BtnStr(BTN_ACTION4));
            Common_Draw("Press %s to stop the channel", Common_BtnStr(BTN_MORE));
            Common_Draw("Press %s and %s to change volume", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN));
            Common_Draw("Press %s and %s to change frequency", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Channel is %s", playing ? "playing" : "stopped");
            Common_Draw("Volume %0.2f", volume);
            Common_Draw("Frequency %0.2f", frequency);
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = dsp->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}

编译效果很好,我是不是错过了一个库?

事实上,解决方案在 C++:Undefined reference to 'FMOD:: X' 上,但我没有看到。我试图在这里为任何遇到同样问题的人说清楚。

"Because the name-mangling systems for such features are not standardized across compilers, few linkers can link object code that was produced by different compilers." https://en.wikipedia.org/wiki/Name_mangling#How_different_compilers_mangle_the_same_functions

所以我使用的 none 个编译器可以处理 Visual Studio 个编译库。