这完全是在黑暗中拍摄的,询问可能是浪费时间,但你永远不会知道。我正在使用GNAT Studio Community 2021(Ada2012(,并试图让一个音频库发挥作用。我很清楚没有专门用Ada编写的音频库,所以它当然是C、C++和一些Ada示例代码的混合。
到目前为止我所做的:
包括我需要的所有目录。勾选";语言;"框下";项目属性";以包括C和C++文件的使用,使它们可见。C/P所需的DLL(包括在音频库文件夹中(到";src";我项目的目录。
到目前为止,完成了上面的所有工作,它确实进行了编译,所以我已经完成了一半。然而,我收到了大量Linker错误,这些错误似乎指的是丢失的函数(它们是C/C++函数,而不是Ada函数(。尽管我将所有相关文件都包括在内,并使其可见,但情况依然如此。
以下是编译器的结果(我从第一行截取了它,因为剩下的只是同一个对象文件中缺少函数defs的延续(。
*
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;
我的猜测是,这个问题是由于Linker开关造成的,也许我需要在项目设置下切换,这样它就可以将C、C++和Ada代码绑定在一起。
我只是在为一个失败的事业而战吗?我很想让它发挥作用,似乎我唯一的问题是告诉链接器声明在哪里(尽管我已经将所有相关文件都包含在项目路径中(。
如果有人能帮忙,我会非常高兴。如果我知道如何为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社区版的工作。我一直在摆弄一些东西,但运气不好。我的一个朋友是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
这就是链接器想要绑定的内容吗?如果是,我该如何告诉Ada/C/C++链接器这样做?哦,出于某种原因-pthread";也无效,这似乎很奇怪。
以下是链接器错误的剪切输出。
Sourceknightmare.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:gnat2021bing++.exe main.o b__main.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjal_h.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjalc_h.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjenemy.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjoal_hpp.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjplayer.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjknightmare.o C:UsersAmynuOneDriveDocumentsKnig
htmareSourceobjsnd.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjsndloop.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjsnd4ada.o libknightmare.a -LC:UsersAmynuOneDriveDocumentsKnightmareSourceobj -LC:UsersAmynuOneDriveDocumentsKnightmareSourceobj -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绑定,但它只适用于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使用gprbuild -P sample
:包含这一点(在macOS上测试,使用包Linker的注释内容,请参阅ocmp.sh
(
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/
目录中,则此操作有效;如果您想将这里的代码用作库,这意味着要创建一个库项目,那么它会变得有点复杂。