英文:
Using Windows libraries with cgo
问题
我正在尝试构建一个使用TagLib的Go包,并且在使用cgo时遇到了一些困难。
我已经编译了TagLib,在taglib
目录中生成了tag.dll
、tag.exp
和tag.lib
。在绑定目录中还有taglib_c.*
二进制文件,但我假设我可以忽略它们。
我该如何使用编译好的库来与Go一起使用?我已经在OS X上的项目源代码中设置了一切,但是在Windows上编译需要做什么?编译好的库(dll或静态库)必须与源代码放在同一个目录中吗?头文件呢?
英文:
I'm trying to build a Go package which makes use of TagLib, and I'm having a little trouble figuring out exactly how to use the compiled libraries with cgo.
I've compiled TagLib, which has spit out tag.dll
, tag.exp
, and tag.lib
in the taglib
dir. There were also the taglib_c.*
binaries in the bindings directory, but I'm assuming that I just ignore those.
How do I make use of the compiled libraries for use with Go? I have everything setup in the source from the project on OS X, but what do I need to do to make it compile on Windows? Does the compiled library (dll or static lib?) have to be in the same directory as the source? What about the headers?
答案1
得分: 2
很不幸,我没有可用的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以供开发使用。如果您查看文件夹的内部,您会发现bin
、lib
和include
的子目录。
这里有个有趣的部分。Windows的标准做法是将动态库文件(*.dll
)放入bin
目录中。一些开源库遵循这个做法,其他一些则将*.dll
文件放入lib
目录中,因为在Unix系统中它们通常放在那里。您需要查看安装生成的lib
目录,并将生成的任何*.dll
文件复制到bin
目录中,以确保正确链接而不需要太多的hack。
现在是Go源代码的部分!在您的源代码顶部,您需要包含cgo
元注释,告诉Go在哪里搜索您想要的库,以及它们的头文件(在安装过程中生成的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 (
// 正常的导入
// ...
)
func main() {
// ...
}
现在,Windows还要求您将*.dll
文件所在的目录添加到PATH
中,所以我们将继续执行这个操作...
/home/noj $ export PATH=$PATH:/home/noj/clibs/bin
现在,我们应该准备好在Go的源代码目录中使用go build
正常编译代码了。
可能的问题:
所以您可能会遇到的一些问题是发现您没有构建taglib所需的必要库,尽管听起来您已经构建了它,所以应该没问题。您会注意到在go源代码中,我添加了标准c++库的LDFLAG
。这是因为taglib使用C++。如果这成为问题,我建议在您的go代码旁边创建一个简单的C程序,与c++库进行交互并为其创建一个C接口。根据我的经验,使用C库和Go比使用C++和Go更容易。
英文:
Unfortunately I don't have a windows machine available to try this out myself, but theoretically, this should work. The steps I have listed are written with a unix perspective, but it should be directly translatable to Windows unless otherwise noted. For Windows, I like to use GitBash for my terminal as it comes with some useful unix tools.
Anyways, I'm gonna work through the entire process to make sure I'm not making any assumptions. first, we'll start with downloading and installing taglib. Assuming that you've downloading the 1.8 tarball that they have available, then I would install it locally in some folder in my computer:
/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
The above code should install taglib locally for development in the folder /home/noj/clibs
. If you take a look at the inside of the folder, you'll find subdirectories for bin
, lib
, and include
.
So here's the funky part. The Windows standard is to dump dynamic lib files (*.dll
) into the bin
directory. Some open source libraries adhere to this and do that, others still dump the *.dll
files in the lib
directory since that's where they usually go in Unix systems. You'll want to take a look at the lib
directory generated by the installation and copy any *.dll
files that are generated over to the bin
directory to make sure proper linking takes place without too much hackery.
Now for the go source code! At the top of your source code, you'll want to include the cgo
meta comments to tell Go where to search for the libraries you want, as well as their headers (the include
directory generated during the installation). Here's some Go source that tries to use the libraries we just built above:
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() {
// ...
}
Now, Windows, also requires you to add the directory where your *.dll
files live to your PATH
, so we'll go ahead and do that...
/home/noj $ export PATH=$PATH:/home/noj/clibs/bin
And now we should be ready to compile the code normally using go build
within the Go's source directory.
Possible Problems:
So some problems you might run into is finding out that you don't have the necessary libraries to build taglib in Windows, though it sounds like you've already built it, so that should be fine. You'll notice that in the go source I added the LDFLAG
for the standard c++ library. This is because taglib uses C++. If this turns out to be a problem, I would create a simple C program alongside your go code that interfaces with the c++ library and creates a C interface for it. From my experience, it's a lot easier to work with a C library and Go than with C++ and Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论