构建Go与Gtk+的C接口

huangapple go评论120阅读模式
英文:

Building Go with C interface to Gtk+

问题

我正在尝试构建一个使用外部C代码作为Gtk+接口的Go程序。

这是我得到的基本Go代码(ui.h.go):

  1. package main
  2. //#cgo pkg-config: gtk+-3.0
  3. //#include "ui.h"
  4. import "C"
  5. func CInit() {
  6. C.Init(nil, 0)
  7. }
  8. func CMain() {
  9. C.Main()
  10. }
  11. func CShowWindow() {
  12. C.ShowWindow()
  13. }
  14. func main() {
  15. CInit()
  16. CShowWindow()
  17. CMain()
  18. }

C代码从Vala编译成一个目标文件(ui.o)和一个头文件(ui.h):

  1. #ifndef __UI_H__
  2. #define __UI_H__
  3. #include <glib.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. G_BEGIN_DECLS
  7. void ShowWindow(void);
  8. void Init(gchar** args, int args_length1);
  9. void Main(void);
  10. G_END_DECLS
  11. #endif

当我尝试运行go build ui.h.go时,我得到以下错误:

  1. # command-line-arguments
  2. /tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_Init':
  3. ./ui.h.go:37: undefined reference to `Init'
  4. /tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_Main':
  5. ./ui.h.go:46: undefined reference to `Main'
  6. /tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_ShowWindow':
  7. ./ui.h.go:55: undefined reference to `ShowWindow'
  8. collect2: error: ld returned 1 exit status

这是合理的,因为我没有提供我的目标文件。但是,如果我在ui.h.go的cgo头部指定它,就像这样...

  1. //#cgo LDFLAGS: ui.o
  2. //#cgo pkg-config: gtk+-3.0
  3. //#include "ui.h"
  4. import "C"

我会得到多重定义错误,好像它被链接了两次。

  1. # command-line-arguments
  2. /usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
  3. ui.o:(.bss+0x0): multiple definition of `window'
  4. /tmp/go-link-461834384/000000.o:/home/oleg/Документы/Projects/rasp/ui.h.go:38: first defined here
  5. ui.o: In function `ShowWindow':
  6. ui.c:(.text+0x0): multiple definition of `ShowWindow'
  7. /tmp/go-link-461834384/000000.o:(.text+0x25): first defined here
  8. ui.o: In function `Init':
  9. ui.c:(.text+0x29): multiple definition of `Init'
  10. /tmp/go-link-461834384/000000.o:(.text+0x4e): first defined here
  11. ui.o: In function `Main':
  12. ui.c:(.text+0x116): multiple definition of `Main'
  13. /tmp/go-link-461834384/000000.o:(.text+0x13b): first defined here
  14. collect2: error: ld returned 1 exit status

如何正确地将我的ui.o文件链接到Go程序中?
谢谢。

英文:

I'm trying to build a Go programm which uses external C code as an interface for Gtk+.

That's the basic Go code I've got (ui.h.go):

  1. package main
  2. //#cgo pkg-config: gtk+-3.0
  3. //#include &quot;ui.h&quot;
  4. import &quot;C&quot;
  5. func CInit() {
  6. C.Init(nil, 0)
  7. }
  8. func CMain() {
  9. C.Main()
  10. }
  11. func CShowWindow() {
  12. C.ShowWindow()
  13. }
  14. func main() {
  15. CInit()
  16. CShowWindow()
  17. CMain()
  18. }

C code is compiled from vala into an object file (ui.o) and a header file (ui.h):

  1. #ifndef __UI_H__
  2. #define __UI_H__
  3. #include &lt;glib.h&gt;
  4. #include &lt;stdlib.h&gt;
  5. #include &lt;string.h&gt;
  6. G_BEGIN_DECLS
  7. void ShowWindow (void);
  8. void Init (gchar** args, int args_length1);
  9. void Main (void);
  10. G_END_DECLS
  11. #endif

When I try go build ui.h.go I get:

  1. # command-line-arguments
  2. /tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_Init&#39;:
  3. ./ui.h.go:37: undefined reference to `Init&#39;
  4. /tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_Main&#39;:
  5. ./ui.h.go:46: undefined reference to `Main&#39;
  6. /tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_ShowWindow&#39;:
  7. ./ui.h.go:55: undefined reference to `ShowWindow&#39;
  8. collect2: error: ld returned 1 exit status

Which is logical, I haven't provided my object file. But if I specify it in cgo header of ui.h.go like that...

  1. //#cgo LDFLAGS: ui.o
  2. //#cgo pkg-config: gtk+-3.0
  3. //#include &quot;ui.h&quot;
  4. import &quot;C&quot;

I get multiple definition error, as if it's being linked twice.

  1. # command-line-arguments
  2. /usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
  3. ui.o:(.bss+0x0): multiple definition of `window&#39;
  4. /tmp/go-link-461834384/000000.o:/home/oleg/Документы/Projects/rasp/ui.h.go:38: first defined here
  5. ui.o: In function `ShowWindow&#39;:
  6. ui.c:(.text+0x0): multiple definition of `ShowWindow&#39;
  7. /tmp/go-link-461834384/000000.o:(.text+0x25): first defined here
  8. ui.o: In function `Init&#39;:
  9. ui.c:(.text+0x29): multiple definition of `Init&#39;
  10. /tmp/go-link-461834384/000000.o:(.text+0x4e): first defined here
  11. ui.o: In function `Main&#39;:
  12. ui.c:(.text+0x116): multiple definition of `Main&#39;
  13. /tmp/go-link-461834384/000000.o:(.text+0x13b): first defined here
  14. collect2: error: ld returned 1 exit status

How do I link my ui.o file to the Go program correctly?
Thank you.

答案1

得分: 2

嗯,我发现cgo与静态库链接得很好。所以我决定将我的ui.o归档为libui.a,并使用#cgo LDFLAGS: -L. -lui进行链接,结果是正确的。

英文:

Well, I figured out that cgo does link well with static libraries. So I decided to archive my ui.o into libui.a and link it using #cgo LDFLAGS: -L. -lui and it worked correctly.

huangapple
  • 本文由 发表于 2015年10月25日 20:35:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/33329744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定