我尝试将音频库静态链接到我的程序中,我使用这个 nimble 包。为了运行它,我需要按照这里所述的方法构建 soloud 库。简而言之,在下载后,我在“build”文件夹中运行了“genie --with-miniaudio-only --platform=x64 vs2017”,并获得了生成动态库和静态库的源代码。目前,我可以使用生成的 dll 和 nimble 包中提供的以下演示程序:
import solouddotnim, times, os
var i, spin = 0
var sl : ptr Soloud
sl = Soloud_create()
discard Soloud_init(sl)
Soloud_setGlobalVolume(sl, 1)
var stream = WavStream_create()
discard WavStream_load(cast[ptr Wav](stream), "test.ogg")
let currentTime = epochTime()
let length = WavStream_getLength(stream)
discard Soloud_play(cast[ptr Soloud](sl), cast[ptr Wav](stream))
while epochTime() - currentTime <= length:
sleep(100)
Soloud_deinit(sl)
Soloud_destroy(sl)
现在讲静态链接的部分。在我使用的nimble包的solouddotnim.nim文件中,我看到了这个部分:
when defined(windows):
const
libname* = "libsoloud.dll"
elif ...
所以我将 Windows 部分简单更改为以下内容,重新安装了 Nimble 包,并将 "soloud_static_x64.lib" 放置在测试项目的 "main.nim" 旁边:
when defined(windows):
const
libname* = "soloud_static_x64.lib"
elif ...
但这并不能解决问题。(在构建时出现“无法打开‘soloud_static_x64.lib’”错误) 每当常量“libname”被使用时,都会有“cdecl”、“importc”和“dynlib”指令。例如:
proc Soloud_create*(): ptr Soloud {.cdecl, importc: "Soloud_create", dynlib: libname.}
因此,“dynlib”告诉Nim在Windows上使用DLL。但是,静态库的编译指示符是什么? 在Nim文档中,我只找到了DynlibOverride用于链接静态库,但我不理解示例,这就是我卡住的地方。我尝试了以下方法:
nim c --dynlibOverride:libname --passL:soloud_static_x64.lib "examples\00-ogg\Example00_ogg.nim"
nim c --dynlibOverride:soloudtotnim --passL:soloud_static_x64.lib "examples\00-ogg\Example00_ogg.nim"
首先,我不知道参数 dynlibOverride 需要什么,其次,两者都编译通过,但并未工作。它期望在exe文件旁边有一个动态库。
我的最后一次尝试是从nimble包中删除所有dynlib pragmas,但现在我无法编译它。
undefined reference to `Soloud_create'
...
Error: execution of an external program failed: 'gcc.exe...
我的知识到此为止了。有人能帮助我吗? 提前感谢。
编辑: 我无法让你们的任何解决方案起作用。我将问题简化,以便每个人都可以重现它: "foo.nim" 包含以下内容:
proc add*(a, b: int): int {.cdecl, exportc.} =
a + b
proc sub*(a, b: int): int {.cdecl, exportc.} =
a - b
.lib 文件可以通过执行以下命令来生成:"nim c --app:staticlib foo.nim"。
现在,为了使用它,我创建了一个名为 "main.nim" 的文件,并将其内容设置为:
{.passL:"foo.lib".}
proc add*(a, b: int):int {.cdecl, importc.}
proc sub*(a, b: int):int {.cdecl, importc.}
echo add(10, 5)
echo sub(10, 5)
如果我只是用"nim c -r main.nim"来构建它,我会得到以下输出和错误:
P:\Nim\LearnCBinding>nim c -r main.nim
Hint: used config file 'C:\nim-1.5.1\config\nim.cfg' [Conf]
Hint: used config file 'C:\nim-1.5.1\config\config.nims' [Conf]
....CC: stdlib_io.nim
CC: stdlib_system.nim
CC: main.nim
Hint: [Link]
foo.lib(@mfoo.nim.c.o):@mfoo.nim.c:(.text+0x1f6): multiple definition of `PreMainInner'
C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o:@mmain.nim.c:(.text+0x120): first defined here
foo.lib(@mfoo.nim.c.o):@mfoo.nim.c:(.text+0x20a): multiple definition of `PreMain'
C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o:@mmain.nim.c:(.text+0x134): first defined here
foo.lib(@mfoo.nim.c.o):@mfoo.nim.c:(.text+0x240): multiple definition of `NimMainInner'
C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o:@mmain.nim.c:(.text+0x16f): first defined here
foo.lib(@mfoo.nim.c.o):@mfoo.nim.c:(.text+0x254): multiple definition of `NimMain'
C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o:@mmain.nim.c:(.text+0x183): first defined here
foo.lib(@mfoo.nim.c.o):@mfoo.nim.c:(.text+0x285): multiple definition of `main'
C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o:@mmain.nim.c:(.text+0x1b4): first defined here
foo.lib(@mfoo.nim.c.o):@mfoo.nim.c:(.text+0x2da): multiple definition of `NimMainModule'
C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o:@mmain.nim.c:(.text+0x209): first defined here
collect2.exe: error: ld returned 1 exit status
Error: execution of an external program failed: 'C:\nim-1.5.1\dist\mingw64\bin\gcc.exe -o P:\Nim\LearnCBinding\main.exe C:\Users\Peter\nimcache\main_d\stdlib_io.nim.c.o C:\Users\Peter\nimcache\main_d\stdlib_system.nim.c.o C:\Users\Peter\nimcache\main_d\@mmain.nim.c.o foo.lib '
由于出现了多个定义错误,我也尝试使用参数"--noMain:on"构建foo.lib,但没有任何变化。
你有同样的问题吗?顺便说一下,我使用的是当前版本的Nim "nim-1.5.1",并重新安装了MingW(使用来自nim的finish.exe)。