用Go构建C++封装

3
我正在尝试在Go中包装C++代码(LabStreamingLayer)。
更新:@dragonx解释了如何使用go build而不使用swig。但是我仍然遇到链接器问题。构建依赖于LSL/liblsl/bin/liblsl.dylib。我该如何告诉go build使用那个文件?我尝试了go build -ldflags“-L ../liblsl/bin -l lsl”app.go,但没有成功。 Go文档说,对于具有.swigcxx扩展名的文件,go build将使用c++选项调用Swig,但是go build抱怨在目录中没有可构建的Go源文件。
  • 平台: Darwin
  • Go 版本: 1.8
  • Swig 版本: 3.0.12
  • clang 版本: 8.0.0

以下是我出现错误的步骤:

  1. 克隆labstreaminglayer repo。
  2. 将文件liblsl_cpp.i重命名为liblsl.swigcxx(我认为这会告诉go build该文件应与swig一起使用)。
  3. cd进入LSL/liblsl-Generic并运行go build。 Go抱怨此目录中没有可构建的Go源文件。

在尝试失败后,我尝试使用Swig。我运行了swig -c++ -go -cgo -intgosize 64 liblsl_cpp.i,它创建了一个.go文件。然后我在该目录中运行了go build,但是它引发了错误:

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1

我不熟悉C ++,所以不确定如何解决链接器问题。我知道这个C ++代码需要文件LSL / liblsl / bin / liblsl64.dylib。我认为这就是必须链接的文件?
我如何在Go中包装这个C ++代码?
这是文件结构:
LSL
├── liblsl
│   ├── bin
│   ├── distros
│   ├── examples
│   ├── external
│   ├── include
│   ├── project
│   ├── src
│   └── testing
└── liblsl-Generic
    ├── AUTOGENERATE\ HOWTO.txt
    ├── examples
    ├── liblsl.swigcxx
    ├── liblsl_c.i
    ├── liblsl_cpp.i
    ├── liblsl_wrap.cxx  # created by Swig
    └── liblsl.go        # created by Swig
2个回答

2

几个月前我遇到过这个问题,解决起来比我想象的要困难得多,但是我不太记得我用什么方法解决了它,但我认为可能是以下这些方面:

  1. Don't call swig manually, it actually makes things a bit more difficult. Clean out the files generate by swig.
  2. Create a file a.go in libsl-Generic with the contents:

    package libsls-Generic
    
  3. In theory you have some other file, say app.go that will use libsls-Generic. Write app.go and import libsls-Generic appropriately.
  4. Use go build app.go. This should build the dependency as well.

我最终找到了如何让go手动包含swig生成的文件,但现在我忘记了具体细节。我记得当使用swig手动生成文件时,重新构建时必须手动删除某些文件。而只使用go运行时,构建步骤就简单多了。


谢谢,这解释了如何在不使用swig的情况下使用go build。但是,我遇到了与使用swig时相似的错误:链接器命令失败(并且找不到许多符号)。链接器无法找到LSL/liblsl/bin/liblsl.dylib。我尝试运行go build -ldflags "-L ../liblsl/bin -l lsl" app.go,但得到了相同的链接器错误。 - jkr
1
你尝试过在cgo注释中指定要链接的dylib吗?https://dev59.com/3GQn5IYBdhLWcg3wiXqd - dragonx

-1
解压 liblsl 发布 tarball,将 liblsl-Generic 克隆到 Go 主目录下的一个文件夹中。 修复 liblsl_cpp.i,使其指向正确的头文件路径。 运行 "swig -go -c++ -cgo -intgosize 32 -package liblsl liblsl_cpp.i"。 在 liblsl.go 中的 "package liblsl" 的上一行的下一个注释之前添加 "// #cgo LDFLAGS: -Wl,-rpath,/usr/local/lib -llsl64"(假设 liblsl64.dylib 位于 "/usr/local/lib"),然后运行 "go install"。 这将使 "liblsl.a" 位于 Go 主目录的 "pkg" 文件夹中,并且您将能够从 Go 程序中导入它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接