windows - 将 Windows 库与 cgo 一起使用

标签 windows go cgo

我正在尝试构建一个使用 TagLib 的 Go 包,而且我在弄清楚如何将已编译的库与 cgo 一起使用时遇到了一些麻烦。

我编译了TagLib,在中吐出了tag.dlltag.exptag.lib >taglib 目录。 bindings 目录中还有 taglib_c.* 二进制文件,但我假设我只是忽略了它们。

如何使用已编译的库与 Go 一起使用?我在 OS X 上的项目的源代码中设置了所有内容,但是我需要做什么才能在 Windows 上编译它?编译后的库(dll 或静态库?)是否必须与源代码位于同一目录中?标题呢?

最佳答案

不幸的是,我没有可用的 Windows 机器来亲自尝试,但理论上,这应该可行。我列出的步骤是从 unix 角度编写的,但除非另有说明,否则它应该可以直接转换为 Windows。对于 Windows,我喜欢使用 GitBash对于我的终端,因为它带有一些有用的 unix 工具。

无论如何,我会检查整个过程以确保我没有做出任何假设。首先,我们将从下载和安装 taglib 开始。假设您下载了 1.8 tarball他们可用,然后我会将其安装在本地计算机的某个文件夹中:

/home/noj $ mkdir -p clibs/src
/home/noj $ cd clibs/src
/home/noj/clibs/src $ tar -xvf /home/noj/Downloads/
/home/noj/clibs/src $ cd taglib-1.8
/home/noj/clibs/src/taglib-1.8 $ cmake -DCMAKE_INSTALL_PREFIX=/home/noj/clibs -DCMAKE_RELEASE_TYPE=Release .
/home/noj/clibs/src/taglib $ make
/home/noj/clibs/src/taglib $ make install

以上代码应该在文件夹/home/noj/clibs 中本地安装用于开发的taglib。如果查看文件夹的内部,您会发现 binlibinclude 的子目录。

所以这是时髦的部分。 Windows 标准是将动态库文件(*.dll)转储到bin 目录中。一些开放源代码库坚持这样做并这样做,其他人仍然将 *.dll 文件转储到 lib 目录中,因为这是它们在 Unix 系统中通常去的地方。您需要查看安装生成的 lib 目录,并将生成的任何 *.dll 文件复制到 bin 目录以确保在没有太多 hackery 的情况下进行正确的链接。

现在是源代码!在源代码的顶部,您需要包含 cgo 元注释来告诉 Go 在哪里搜索您想要的库,以及它们的 header (include 安装时生成的目录)。这是一些尝试使用我们刚刚在上面构建的库的 Go 源代码:

package main

/*
#cgo LDFLAGS: -L/home/noj/clibs/lib -ltag -lstdc++
#cgo CFLAGS: -I/home/noj/clibs/include/taglib

#include <taglib.h>
*/
import "C"

import (
  // normal imports
  // ...
)

func main() {
  // ...
}

现在,Windows 还要求您将您的 *.dll 文件所在的目录添加到您的 PATH,因此我们将继续这样做。 .

/home/noj $ export PATH=$PATH:/home/noj/clibs/bin

现在我们应该准备好在 Go 的源目录中使用 go build 正常编译代码。

可能的问题:

因此您可能遇到的一些问题是发现您没有必要的库来在 Windows 中构建 taglib,尽管听起来您已经构建了它,所以这应该没问题。您会注意到,在 go 源代码中,我为标准 c++ 库添加了 LDFLAG。这是因为 taglib 使用 C++。如果这证明是一个问题,我会创建一个简单的 C 程序和你的 go 代码,它与 c++ 库接口(interface)并为它创建一个 C 接口(interface)。根据我的经验,使用 C 库和 Go 比使用 C++ 和 Go 更容易。

关于windows - 将 Windows 库与 cgo 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16492121/

相关文章:

c++ - Boost 链接器错误 : Unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::get_system_category(void)"

c++ - 接收大量 (r) UDP 流量时 CPU 负载高 (Windows)

c# - UWP 应用程序不会在第二台机器上启动

.net - stdout 是否附加了缓冲区大小?

go - 在 Go 中设置包路径

go - worker 循环中使用多WG的正确方法是吗?

python - 使用 `gopy` ,如何正确地将 []string 从 Python 传递给 Go?

c - 直接C指针转换

go - 使用 cgo 将字符串传递给 win32 函数

c - 当C库使用不透明结构指针时,如何解决cgo中的 "bad pointer in write barrier"panic