使用cgo包装<dispatch / dispatch.h>时生成错误

I'm playing around with XPC, GCD and go but I hit a quick wall when my code was failing to compile with the following error messages (which I don't understand):

main(__DATA/__const): unexpected reloc for dynamic symbol _NSConcreteGlobalBlock main(__DATA/__const): unhandled relocation for _NSConcreteGlobalBlock (type 28 rtype 120)

I am compiling using go build the code that follows:

main.go

package main

/*
#include <xpc/xpc.h>
#include "wrapper.h"
*/
import "C"

import (
    "fmt"
)

//export HandleXPCEvent
func HandleXPCEvent(event C.xpc_object_t) {
    fmt.Println("Event was handled")
}

func main() {
    name := C.CString("com.example.xpc")
    queue := C.dispatch_queue_create(name, nil)
    conn := C.xpc_connection_create(name, queue)
    C.set_event_handler(conn)

    //C.xpc_connection_resume(conn)
}

wrapper.h

#ifndef _WRAPPER_H_
#define _WRAPPER_H_

#include <stdlib.h>
#include <stdio.h>
#include <xpc/xpc.h>

xpc_connection_t connect( char* name);
void set_event_handler(xpc_connection_t connection);

#endif

wrapper.c

#include "wrapper.h"
#include <dispatch/dispatch.h>

extern void HandleXPCEvent(xpc_object_t);

xpc_connection_t connect( char* name) {
    dispatch_queue_t queue = dispatch_queue_create(name,0);
    return xpc_connection_create(name,queue);
}

void set_event_handler(xpc_connection_t connection) {
    xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
        xpc_retain(event);
        // Call Go function
        HandleXPCEvent(event);
    });
}

I'm I doing something wrong? Is this some kind of go bug or how can this be fixed?


Update:

I ran go build -x -work on my project and I got the following output:

➣ go build -x -work
WORK=/var/folders/fb/bgfqk8wx5x16w7yh2cg50vrw0000gn/T/go-build524335717
mkdir -p $WORK/github.com/gabrielayuso/go-xpc/_obj/
mkdir -p $WORK/github.com/gabrielayuso/go-xpc/_obj/exe/
cd /Users/gabrielayuso/Documents/Workspace/Projects/go/src/github.com/gabrielayuso/go-xpc
/usr/local/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/github.com/gabrielayuso/go-xpc/_obj/ -- -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ main.go
/usr/local/go/pkg/tool/darwin_amd64/6c -F -V -w -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ -I /usr/local/go/pkg/darwin_amd64 -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_defun.6 -D GOOS_darwin -D GOARCH_amd64 $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_defun.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -print-libgcc-file-name
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_main.o -c $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_main.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_export.o -c $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_export.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ -o $WORK/github.com/gabrielayuso/go-xpc/_obj/main.cgo2.o -c $WORK/github.com/gabrielayuso/go-xpc/_obj/main.cgo2.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ -o $WORK/github.com/gabrielayuso/go-xpc/_obj/wrapper.o -c ./wrapper.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_.o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_main.o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_export.o $WORK/github.com/gabrielayuso/go-xpc/_obj/main.cgo2.o $WORK/github.com/gabrielayuso/go-xpc/_obj/wrapper.o
/usr/local/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/github.com/gabrielayuso/go-xpc/_obj/ -dynimport $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_.o -dynout $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_import.c
/usr/local/go/pkg/tool/darwin_amd64/6c -F -V -w -I $WORK/github.com/gabrielayuso/go-xpc/_obj/ -I /usr/local/go/pkg/darwin_amd64 -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_import.6 -D GOOS_darwin -D GOARCH_amd64 $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_import.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_all.o $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_export.o $WORK/github.com/gabrielayuso/go-xpc/_obj/main.cgo2.o $WORK/github.com/gabrielayuso/go-xpc/_obj/wrapper.o -Wl,-r -nostdlib /usr/llvm-gcc-4.2/bin/../lib/gcc/i686-apple-darwin11/4.2.1/x86_64/libgcc.a
/usr/local/go/pkg/tool/darwin_amd64/6g -o $WORK/github.com/gabrielayuso/go-xpc/_obj/_go_.6 -p github.com/gabrielayuso/go-xpc -D _/Users/gabrielayuso/Documents/Workspace/Projects/go/src/github.com/gabrielayuso/go-xpc -I $WORK $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_gotypes.go $WORK/github.com/gabrielayuso/go-xpc/_obj/main.cgo1.go
/usr/local/go/pkg/tool/darwin_amd64/pack grcP $WORK $WORK/github.com/gabrielayuso/go-xpc.a $WORK/github.com/gabrielayuso/go-xpc/_obj/_go_.6 $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_import.6 $WORK/github.com/gabrielayuso/go-xpc/_obj/_cgo_defun.6 $WORK/github.com/gabrielayuso/go-xpc/_obj/_all.o
cd .
/usr/local/go/pkg/tool/darwin_amd64/6l -o $WORK/github.com/gabrielayuso/go-xpc/_obj/exe/a.out -L $WORK $WORK/github.com/gabrielayuso/go-xpc.a
# github.com/gabrielayuso/go-xpc
main(__DATA/__const): unexpected reloc for dynamic symbol _NSConcreteGlobalBlock
main(__DATA/__const): unhandled relocation for _NSConcreteGlobalBlock (type 28 rtype 120)

Content of $WORK dir as generated by go build -x -work: go-xpc_work.zip

I'm not very familiar with compiling and linking therefore I can't make much sense of this output. I just noticed that _cgo_import.c a file generated by cgo (with options -dynimport and -dynout) has #pragma cgo_import_dynamic _NSConcreteGlobalBlock _NSConcreteGlobalBlock "" in the first line which is related to the error message the linker gave.

Hope this information can help to find out what the problem is and how to solve it.

I don't know much about those libraries but nothing jumps out at me with the code you have here.

Some useful debug output can be obtained from go build -x -work which will print the commands and the working directory for you.

The working directory will be left untouched so you can go look at the code cgo generates for you. That plus the commands it will print for you should get you started on tracking down the problem.

I have a wrapper written up for using Go and XPC in Cocoa Applications.

It's located here:

https://github.com/aventurella/go-xpc