c++ - 第三方音频库链接器问题

标签 c++ c ada

这完全是在黑暗中拍摄,问这个问题可能是浪费时间,但你永远不知道。我正在使用 GNAT Studio Community 2021 (Ada2012) 并尝试让音频库正常工作。我很清楚专门用 Ada 编写的音频库为零,所以当然它是 C、C++ 与一些 Ada 示例代码的混合。

到目前为止我做了什么:

包括我需要的所有目录。 勾选“项目属性”下的“语言”框以包含 C 和 C++ 文件的使用,使其可见。 将所需的 DLL(包含在音频库文件夹中)C/P 到我的项目的“src”目录中。

到目前为止,完成上述所有操作后,它确实可以编译,所以我已经成功了一半。但是,我收到大量链接器错误,这些错误似乎是指缺少的函数(它们是 C/C++ 函数,而不是 Ada)。尽管我包含了所有相关文件并使它们可见,但还是出现了这种情况。

这是编译器输出的内容(我已从第一行将其裁剪掉,因为其余的只是同一目标文件中缺少函数定义的延续)。

*

Compile
[Ada]          main.adb
Bind
[gprbind]      main.bexch
[Ada]          main.ali
Link
[link]         main.adb
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe:
libamos.a(oal.o):oal.cpp:(.text+0x10): undefined reference to
`__imp_alcOpenDevice'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe:
libamos.a(oal.o):oal.cpp:(.text+0x4c): undefined reference to
`__imp_alcCreateContext’

这是我编写的代码,用于测试一切是否正常。

with al_h;
with alc_h;
with snd;
with snd4ada;
with sndloop;


procedure Main is
begin
    null;
end Main;

作为引用,这里是该库附带的工作代码。

with text_io; use text_io;
with snd4ada;
with interfaces.c;
with interfaces.c.strings;
with ada.command_line;

procedure one is

    -- plays WAV file given on command line

    subtype glint is interfaces.c.int;

    linestr: string(1..80);
    last: natural;
    music: glint;

begin

if ada.command_line.argument_count = 1 then

    declare
        title : string := Ada.Command_Line.Argument(1);
    begin --declare


        snd4ada.initSnds;

        music:=snd4ada.initLoop( 
            interfaces.c.Strings.New_string(title));


        put_line("Hit <enter> to begin");
        get_line(linestr,last);

        snd4ada.playLoop(music);

        put_line("hit <enter> to end");
        get_line(linestr,last);

        snd4ada.stopLoop(music);

        snd4ada.termSnds;

    end; --declare

end if;
end one;

我的猜测是问题是由于链接器开关造成的,也许我需要在项目设置下进行切换,以便它可以将 C、C++ 和 Ada 代码绑定(bind)在一起。

我只是在这里与失败的事业作斗争吗?我很想让它工作,似乎我唯一的问题是告诉链接器声明在哪里(即使我已将所有相关文件包含到项目路径中)。

如果有人能提供帮助,我会非常高兴。如果我知道如何为 Ada 编写自己的音频库,但似乎第三方是唯一的出路。顺便说一句 - 我确实尝试过让 BASS 工作,但那是行不通的。这是最接近工作的 - 而且很烦人,因为示例代码生成了一个确实工作的 .exe。所以这一定是我对链接器做错了什么。

编辑

这是我的 GPR 文件的内容。

project Amos is

   for Source_Dirs use ("src", "External Libs/adaOal19oct21/adaOpenAL", "External Libs/adaOal19oct21/adaOpenAL/OalBinding", "External Libs/adaOal19oct21/adaOpenAL/OalBinding/incoal");
   for Object_Dir use "obj";
   for Main use ("main.adb");
   for Languages use ("Ada", "C", "C++");

end Amos;

大家好。是的,我仍然致力于让 Ada Open AL 在 GNAT 2021 社区版上运行。我一直在切换一些东西,但没有运气。我的一个 friend 是 Ada 开发人员,他说他可以让它在使用 Windows NT 的旧 IDE 上运行?

我不断更改我的 GPR 文件。同样,一切都通过了编译器,但在链接器处失败,因为它找不到目标文件,即使我已经添加了所有开关。这是我当前的 GPR 文件。

project Knightmare is

   for Source_Dirs use ("src", "../Libs/adaOpenAL", "../Libs/adaOpenAL/OalBinding", "../Libs/adaOpenAL/OalBinding/incoal");
   for Object_Dir use "obj";
   for Main use ("main.adb");
   for Languages use ("Ada", "C", "C++");

   package Linker is
      for Switches ("c++") use ("g++", "-c", "-fdump-ada-spec", "-C", "oal.hpp", "-Iincoal");
   end Linker;

   package Compiler is
        for Switches ("c++") use ("g++", "-c", "../OalBinding/oal.cpp", "/-std=c++11", "/-fpermissive",
                                  "/-I..", "/-I../OalBinding", "/-I../OalBinding/incoal");
   end Compiler;

end Knightmare;

“项目属性”下检查的语言是 Ada、C 和 C++。包括所有必需的文件夹(如 GPR 中所示)。这可能是我缺少的“依赖”吗?我已经查看了下面善良的用户和评论中提到的 SH(shell 脚本),但我无法将 Shell 脚本添加到项目中,因为它说我没有编译器来处理它。我今天确实找到了这个文件,但这可能是问题所在。

rm *.o
rm obj/*


g++ -c ../OalBinding/oal.cpp \
-std=c++11 \
-fpermissive \
-I.. \
-I../OalBinding \
-I../OalBinding/incoal



gnatmake $1 \
-D obj \
-I.. -I../OalBinding \
-largs \
-lc++ \
oal.o \
\
-framework CoreAudio \
-framework AudioUnit \
-framework AudioToolBox \
-framework OpenAL \
-pthread 

这是链接器正在寻找的绑定(bind)所有内容的东西吗?如果是这样,我如何告诉 Ada/C/C++ 链接器这样做?哦,由于某种原因,开关“-pthread”也无效,这看起来很奇怪。

这是链接器错误的输出片段。

\Source\knightmare.gpr
Bind
   [gprbind]      main.bexch
   [Ada]          main.ali
Link
   [link]         main.adb
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x10): undefined reference to `__imp_alcOpenDevice'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x4c): undefined reference to `__imp_alcCreateContext'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x6c): undefined reference to `__imp_alcMakeContextCurrent'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x88): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x9d): undefined reference to `__imp_alGenBuffers'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0xa6): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x113): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x13c): undefined reference to `__imp_alBufferData'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x145): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x1a8): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x1bd): undefined reference to `__imp_alGenSources'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x1c6): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x22b): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x245): undefined reference to `__imp_alSourcei'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x24e): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x2be): undefined reference to `__imp_alDeleteSources'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x2d3): undefined reference to `__imp_alDeleteBuffers'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x2f7): undefined reference to `__imp_alcDestroyContext'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x307): undefined reference to `__imp_alcCloseDevice'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x325): undefined reference to `__imp_alSourceStop'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x343): undefined reference to `__imp_alSourcePlay'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x36d): undefined reference to `__imp_alGetSourcei'
collect2.exe: error: ld returned 1 exit status
gprbuild: link of main.adb failed
gprbuild: failed command was: c:\gnat\2021\bin\g++.exe main.o b__main.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\al_h.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\alc_h.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\enemy.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\oal_hpp.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\player.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\knightmare.o C:\Users\Amynu\OneDrive\Documents\Knig
htmare\Source\obj\snd.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\sndloop.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\snd4ada.o libknightmare.a -LC:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\ -LC:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\ -LC:/gnat/2021/lib/gcc/x86_64-w64-mingw32/10.3.1/adalib/ C:/gnat/2021/lib/gcc/x86_64-w64-mingw32/10.3.1/adalib/libgnarl.a C:/gnat/2021/lib/gcc/x86_64-w64-mingw32/10.3.1/adalib/libgnat.a -Xlinker --stack=0x200000
,0x1000 -mthreads -shared-libgcc -o main.exe
[2021-11-24 10:53:20] process exited with status 4, 100% (11/11), elapsed time: 01.42s
Could not execute "debug set line breakpoint"

我知道我即将让它发挥作用。我什至给 Ada Open Al 的创建者发了电子邮件,但已经三天没有人回复我了。关于如何让它在 GNAT 2021 社区下工作的 YouTube 视频为零,而且网络上的信息非常稀疏且无用。

如果有人能给我指出一个可能的解决方案,我将永远为此感到高兴。顺便说一句,我知道 Ada 有一个 SDL 绑定(bind),但它只适用于 Win32 机器(它相当旧),所以这也是不可能的。

最佳答案

lcmp.sh包含

rm *.o
rm obj/*


# first, create oal.o:
g++ ../OalBinding/oal.cpp -c \
-D obj \
-I.. \
-I../OalBinding \
-I../OalBinding/incoal


gnatmake $1 -o $1_gnu \
-D obj \
-O3 -gnat12 -I.. -I../OalBinding \
-largs \
oal.o \
-lstdc++ \
-lopenal -lpthread

所以我希望你的 GPR 包含这个(在 macOS 上使用包链接器的注释掉内容进行测试,请参阅 ocmp.sh )使用 gprbuild -P sample :

project Sample is

   for Languages use ("ada", "c++");
   for Object_Dir use "obj";
   for Create_Missing_Dirs use "true";
   for Source_Dirs use (".", "..", "../OalBinding");

   for Main use ("one.adb", "two.adb");
   for Exec_Dir use ".";  -- unless you want the executables in Object_Dir!

   package Compiler is
      for Default_Switches ("ada") use ("-O3", "-gnat12");

      --  You'd have thought that these switches should be "-I..",
      --  "-I../OalBinding" etc; sadly, the compilation is run from
      --  the Object_Dir, ./obj, so the include directories are one
      --  more level up.
      --
      --  Someone put me right if there's a better way to do this!
      for Default_Switches ("c++") use
        ("-I../..", "-I../../OalBinding", "-I../../OalBinding/incoal");
   end Compiler;

   package Linker is
      for Default_Switches ("ada") use
        ("-lstdc++", "-lopenal", "-lpthread");

      -- These are the linker switches for macOS, see ocmp.sh.
      -- for Default_Switches ("ada") use
      --   ("-lstdc++",
      --    "-framework", "CoreAudio",
      --    "-framework", "AudioUnit",
      --    "-framework", "AudioToolBox",
      --    "-framework", "OpenAL");
   end Linker;

end Sample;

如果您的测试程序位于 adaExample/ 中,则此方法有效。目录;如果您想将此处的代码用作库(这意味着创建一个库项目),事情会变得更加复杂。

关于c++ - 第三方音频库链接器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70019773/

相关文章:

c - 如何使用生成文件选项在 Visual Studio 2005 中链接 *.c 文件?

c - 使用 C 程序计算数组中间元素的总和

ada - SPARK 中的任务需要按顺序进行细化

ada - 使用 SPARK 证明选择排序算法

c++ - 分配 : *** error for object 0x00: pointer being freed was not allocated

c++ - 如何检查可变参数模板中的所有类型都可以转换为 size_t?

c++ - boost multi_index : retrieve unique values of a non-unique key

c - Linux 上的时区转换 C API,有人知道吗?

ada - SPARK-Ada 使用 GNATProve 假设 GCC 内在函数的后置条件

android - 我想在 android 中将音频服务器 (/frameworks/av/media/audioserver) 构建为 64 位,但它无法启动