gpt4 book ai didi

static-libraries - 尼姆 : Use a static library

转载 作者:行者123 更新时间:2023-12-05 06:09:43 28 4
gpt4 key购买 nike

我试图获得一个静态链接到我的程序的音频库。我用 this灵活的包。为了让它运行,我必须按照描述构建 soloud 库 here .下载后不久,我在“build”文件夹中运行了“genie --with-miniaudio-only --platform=x64 vs2017”,并获得了生成动态和静态库的源代码。现在我可以从 nimble 包中运行以下演示程序以及生成的 dll:

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-package 并将“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。但是静态库的 pragma 是什么?在 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 pragma。但是现在我无法编译它。

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”并使用 nim 的 finish.exe 重新安装了 MingW。

最佳答案

我会尽力帮助您解决您遇到的以下错误:

undefined reference to `Soloud_create'

但我假设您已经配置了您的环境,因此您可以使用 visual studio 编译器编译您的 nim 程序(通过将 --cc:vcc 添加到您的编译命令)这是因为您似乎已经拥有 visual studio 2017,并且正在使用它编译 soloud 静态库。当您同时使用一个编译器进行编译时,我认为这是最佳选择:静态库和将使用它的可执行文件。

使用一些文本/十六进制编辑器打开静态库 (soloud_static_x64.lib) 并搜索“Soloud_create”。我猜你不会找到任何东西。那是为什么呢?因为出于某种原因,作者决定不在静态库项目中包含“C 接口(interface)”。所以它只包含 C++ 符号,而不包含我们的 solouddotnim.nim 模块所需的纯 C 符号。

让我们试着找出为此需要的 .cpp 文件。我在 Soloud 的官方网站上注意到此信息 - http://sol.gfxile.net/soloud/c_api.html
所以我想我们只需要一个文件:soloud_c.cpp
让我们尝试将它包含在您使用 Genie 生成的 SoloudStatic.vcxproj 文件中。像这样:

..
<ClCompile Include="..\..\src\c_api\soloud_c.cpp">
</ClCompile>
..

并重新编译我们的静态库。我在 powershell 中使用这个命令:

& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\MSBuild.exe' /p:PlatformToolset=v142`;WindowsTargetPlatformVersion=10`;Configuration=Release`;Platform=x64 .\SoloudStatic.vcxproj

但是你可以按你想要的方式编译。只要确保它的架构真的是 x64。你可以用这个命令检查它:

dumpbin /headers soloud_static_x64.lib | more

最后只需将它与您的 nim 文件链接起来。将此行添加到顶部:

{.link:"soloud_static_x64.lib".}

并使用此命令编译 nim 文件:

nim c --cc:vcc --dynlibOverride:libsoloud.dll -r "examples\00-ogg\Example00_ogg.nim"

关于static-libraries - 尼姆 : Use a static library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64677151/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com