CGO链接错误:未定义引用`MemoryFreeLibrary'

时间:2018-01-27 04:07:43

标签: go cgo

我试图用Go包装一个C库。该库使用CMake构建并生成静态库文件。我在#cgo文件的开头添加了.go内容,其中包含正确的CFLAGSLDFLAGS,但是,在运行{{{}}时出现undefined reference错误1}}。

这是我的代码:

go build memorymodule.go

以下是package main /* #cgo CFLAGS: -IMemoryModule #cgo LDFLAGS: MemoryModule/build/MemoryModule.a #include "MemoryModule/MemoryModule.h" */ import "C" import ( "fmt" "io/ioutil" "os" "unsafe" ) const SIZE int = 1024 func end(msg string) { fmt.Println(msg) os.Exit(1) } func check(err error, msg string) { if err != nil { end(msg) } } func main() { bin, err := ioutil.ReadFile(os.Args[0]) check(err, "error reading file") // Convert the args passed to this program into a C array of C strings var cArgs []*C.char for _, goString := range os.Args { cArgs = append(cArgs, C.CString(goString)) } // Load the reconstructed binary from memory handle := C.MemoryLoadLibraryEx( unsafe.Pointer(&bin[0]), // void *data (C.size_t)(len(bin)), // size_t (*[0]byte)(C.MemoryDefaultAlloc), // Alloc func ptr (*[0]byte)(C.MemoryDefaultFree), // Free func ptr (*[0]byte)(C.MemoryDefaultLoadLibrary), // loadLibrary func ptr (*[0]byte)(C.MemoryDefaultGetProcAddress), // getProcAddress func ptr (*[0]byte)(C.MemoryDefaultFreeLibrary), // freeLibrary func ptr unsafe.Pointer(&cArgs[0]), // void *userdata ) // Execute binary C.MemoryCallEntryPoint(handle) // Cleanup C.MemoryFreeLibrary(handle) } go build ...帮助调试的结果:

-x

有趣的是,如果我使用make而不是CMake(通过编辑我的Makefile)编译MemoryModule依赖项,以便它生成一个目标文件而不是静态库文件,并修改我的源代码以链接到那个,我得到没问题:

cd /home/wlaw/go-memory-module
i686-w64-mingw32-gcc -I . -m32 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -o $WORK/command-line-arguments/_obj/_cgo_.o $WORK/command-line-arguments/_obj/_cgo_main.o $WORK/command-line-arguments/_obj/_cgo_export.o $WORK/command-line-arguments/_obj/memorymodule.cgo2.o -g -O2 MemoryModule/build/MemoryModule.a
# command-line-arguments
/tmp/go-build590803163/command-line-arguments/_obj/_cgo_main.o:_cgo_main.c:(.data+0x0): undefined reference to `MemoryDefaultLoadLibrary'
/tmp/go-build590803163/command-line-arguments/_obj/_cgo_main.o:_cgo_main.c:(.data+0x4): undefined reference to `MemoryDefaultGetProcAddress'
/tmp/go-build590803163/command-line-arguments/_obj/_cgo_main.o:_cgo_main.c:(.data+0x8): undefined reference to `MemoryDefaultFreeLibrary'
/tmp/go-build590803163/command-line-arguments/_obj/_cgo_main.o:_cgo_main.c:(.data+0xc): undefined reference to `MemoryDefaultFree'
/tmp/go-build590803163/command-line-arguments/_obj/_cgo_main.o:_cgo_main.c:(.data+0x10): undefined reference to `MemoryDefaultAlloc'
/tmp/go-build590803163/command-line-arguments/_obj/memorymodule.cgo2.o: In function `cgo_50ced23471ff_Cfunc_MemoryCallEntryPoint':
/tmp/go-build/command-line-arguments/_obj/cgo-gcc-prolog:40: undefined reference to `MemoryCallEntryPoint'
/tmp/go-build590803163/command-line-arguments/_obj/memorymodule.cgo2.o: In function `cgo_50ced23471ff_Cfunc_MemoryLoadLibraryEx':
/tmp/go-build/command-line-arguments/_obj/cgo-gcc-prolog:76: undefined reference to `MemoryLoadLibraryEx'
/tmp/go-build590803163/command-line-arguments/_obj/memorymodule.cgo2.o: In function `cgo_50ced23471ff_Cfunc_MemoryFreeLibrary':
/tmp/go-build/command-line-arguments/_obj/cgo-gcc-prolog:54: undefined reference to `MemoryFreeLibrary'
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'all' failed
make: *** [all] Error 2

我的Makefile供参考:

package main

/*
#cgo CFLAGS: -IMemoryModule
#cgo LDFLAGS: MemoryModule/MemoryModule.o
#include "MemoryModule/MemoryModule.h"
*/
import "C"
...

任何帮助将不胜感激!

Git项目:https://github.com/wheelerlaw/go-memory-module

更新

好的,所以我偶然发现this问题。因此,如果我将ifneq ("$(shell which i686-w64-mingw32-gcc)","") compiler = i686-w64-mingw32-gcc else compiler = i586-mingw32msvc-gcc endif # Build the dependencies first (subdirs), then move onto the meat and potatoes. all: MemoryModule CC=$(compiler) CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -x memorymodule.go # Dependency build. SUBDIRS = MemoryModule subdirs: $(SUBDIRS) $(SUBDIRS): $(MAKE) -C $@ # Override default subdir build behavior (make) with cmake. MemoryModule: [ "`ls -A MemoryModule`" ] || git submodule update --init # $(MAKE) -C $@ cmake -HMemoryModule -BMemoryModule/build cmake --build MemoryModule/build --target MemoryModule # Clean targed. CLEANDIRS = $(SUBDIRS:%=clean-%) clean: $(CLEANDIRS) rm -f memorymodule.exe $(CLEANDIRS): $(MAKE) -C $(@:clean-%=%) clean test: $(MAKE) -C tests test .PHONY: subdirs $(INSTALLDIRS) $(SUBDIRS) clean test 命令更改为:

go build

从:

GOOS="windows" GOARCH="amd64" CGO_ENABLED="1" CC="x86_64-w64-mingw32-gcc" go build -x

......它有效。所以看起来不同的拱门之间不兼容。我将下载32位版本的Go,看看是否有帮助。

但我不明白的是,当我将C库编译成对象而不是静态库时,即使使用不匹配的arch,程序也可以正常编译。有什么想法吗?

0 个答案:

没有答案