这完全是在黑暗中拍摄,问这个问题可能是浪费时间,但你永远不知道。我正在使用 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/