FAQ
Hello

I'm trying to figure out how to use cgo to correctly call between C code in
different packages. I have some code similar to this:

* package a contains a Go function A() that calls C.a() using cgo, via
import "C" in the usual way, for the a() function in a.c file in the package

* package b contains a Go function B() that calls the a.A() Go function

What I would like to do is to rewrite b.B() in C, and have that b.b()
directly invoke a.a() (i.e. the C version of the a function) from package a.

Is there a supported way to do this? (I won't go so far as to call it
"approved" ;-).

thanks
bill



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Ian Lance Taylor at Oct 20, 2015 at 10:23 pm

    On Tue, Oct 20, 2015 at 1:42 PM, wrote:
    I'm trying to figure out how to use cgo to correctly call between C code in
    different packages. I have some code similar to this:

    * package a contains a Go function A() that calls C.a() using cgo, via
    import "C" in the usual way, for the a() function in a.c file in the package

    * package b contains a Go function B() that calls the a.A() Go function

    What I would like to do is to rewrite b.B() in C, and have that b.b()
    directly invoke a.a() (i.e. the C version of the a function) from package a.

    Is there a supported way to do this? (I won't go so far as to call it
    "approved" ;-).
    C functions, unlike Go functions, live in a global name space. So if
    a.a is not static, then b.b can simply call it by name. If a.a is
    static, then this can not be done.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Billtohara at Oct 20, 2015 at 11:04 pm

    On Tuesday, October 20, 2015 at 3:24:10 PM UTC-7, Ian Lance Taylor wrote:
    On Tue, Oct 20, 2015 at 1:42 PM, <billt...@gmail.com <javascript:>>
    wrote:
    I'm trying to figure out how to use cgo to correctly call between C code in
    different packages. I have some code similar to this:
    C functions, unlike Go functions, live in a global name space. So if
    a.a is not static, then b.b can simply call it by name. If a.a is
    static, then this can not be done.

    Ian


    a.a isn't static, but when trying this I trip over on linking. Hints
    appreciated!

    For example, here are packages ap and bp. (Using package names a and b here
    trips over a symbol lookup rule, I believe, when trying to invoke C.a you
    get the package rather than the C function?).

    $ find src -type f
    src/ap/a.c
    src/ap/a.go
    src/ap/a.h
    src/bp/b.go
    src/bp/b.h
    src/bp/b.c

    a.h:
    void ca(void);

    a.c:
    #include <stdio.h>
    void ca(void){printf("ap.ca()\n");}

    a.go:
    package ap

    import "fmt"

    //#include "a.h"
    import "C"

    func A() {
    fmt.Println("ap.A()")
    C.ca()
    }

    b.h:
    void cb(void);

    b.c:
    #include "ap/a.h"
    void cb(void){ca();}

    b.go:
    package main

    import "fmt"
    import "ap"

    //#include "b.h"
    // #cgo CFLAGS: -I..
    import "C"

    func B() { fmt.Println("ab.B()")
    C.cb()
    }

    func main() {
    ap.A()
    B()
    }


    $ go install -x bp
    WORK=/tmp/go-build146765608
    mkdir -p $WORK/bp/_obj/
    mkdir -p $WORK/bp/_obj/exe/
    cd /home/bill/test/src/bp
    CGO_LDFLAGS="-g" "-O2" /usr/local/tensyr/tools/go/pkg/tool/linux_amd64/cgo
    -objdir $WORK/bp/_obj/ -importpath bp -- -I $WORK/bp/_obj/ -I.. b.go
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -print-libgcc-file-name
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/_cgo_main.o -c $WORK/bp/_obj/_cgo_main.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/_cgo_export.o -c $WORK/bp/_obj/_cgo_export.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/b.cgo2.o -c $WORK/bp/_obj/b.cgo2.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/b.o -c ./b.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/bp/_obj/_cgo_.o
    $WORK/bp/_obj/_cgo_main.o $WORK/bp/_obj/_cgo_export.o
    $WORK/bp/_obj/b.cgo2.o $WORK/bp/_obj/b.o -g -O2
    # bp
    /tmp/go-build146765608/bp/_obj/b.o: In function `cb':
    src/bp/b.c:4: undefined reference to `ca'
    collect2: error: ld returned 1 exit status

    Trying to use cgo LDFLAGS: ../../pkg/linux_amd64/ap.a doesn't work since
    ap.a doesn't have symbols and running ranlib breaks it (i.e. it no longer
    resembles a go package).

    On the other hand, leaving out the call to ca() in b.c gives a binary which
    correctly produces the expected output:

    $ ./bin/bp
    ap.A()
    ap.ca()
    ab.B()
    $

    thanks!

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Oct 20, 2015 at 11:17 pm

    On Tue, Oct 20, 2015 at 4:04 PM, wrote:
    On Tuesday, October 20, 2015 at 3:24:10 PM UTC-7, Ian Lance Taylor wrote:
    On Tue, Oct 20, 2015 at 1:42 PM, wrote:
    I'm trying to figure out how to use cgo to correctly call between C code
    in
    different packages. I have some code similar to this:
    C functions, unlike Go functions, live in a global name space. So if
    a.a is not static, then b.b can simply call it by name. If a.a is
    static, then this can not be done.
    a.a isn't static, but when trying this I trip over on linking. Hints
    appreciated!

    For example, here are packages ap and bp. (Using package names a and b here
    trips over a symbol lookup rule, I believe, when trying to invoke C.a you
    get the package rather than the C function?).

    $ find src -type f
    src/ap/a.c
    src/ap/a.go
    src/ap/a.h
    src/bp/b.go
    src/bp/b.h
    src/bp/b.c

    a.h:
    void ca(void);

    a.c:
    #include <stdio.h>
    void ca(void){printf("ap.ca()\n");}

    a.go:
    package ap

    import "fmt"

    //#include "a.h"
    import "C"

    func A() {
    fmt.Println("ap.A()")
    C.ca()
    }

    b.h:
    void cb(void);

    b.c:
    #include "ap/a.h"
    void cb(void){ca();}

    b.go:
    package main

    import "fmt"
    import "ap"

    //#include "b.h"
    // #cgo CFLAGS: -I..
    import "C"

    func B() { fmt.Println("ab.B()")
    C.cb()
    }

    func main() {
    ap.A()
    B()
    }


    $ go install -x bp
    WORK=/tmp/go-build146765608
    mkdir -p $WORK/bp/_obj/
    mkdir -p $WORK/bp/_obj/exe/
    cd /home/bill/test/src/bp
    CGO_LDFLAGS="-g" "-O2" /usr/local/tensyr/tools/go/pkg/tool/linux_amd64/cgo
    -objdir $WORK/bp/_obj/ -importpath bp -- -I $WORK/bp/_obj/ -I.. b.go
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -print-libgcc-file-name
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/_cgo_main.o -c $WORK/bp/_obj/_cgo_main.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/_cgo_export.o -c $WORK/bp/_obj/_cgo_export.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/b.cgo2.o -c $WORK/bp/_obj/b.cgo2.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/bp/_obj/ -g -O2
    -I.. -o $WORK/bp/_obj/b.o -c ./b.c
    gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/bp/_obj/_cgo_.o
    $WORK/bp/_obj/_cgo_main.o $WORK/bp/_obj/_cgo_export.o $WORK/bp/_obj/b.cgo2.o
    $WORK/bp/_obj/b.o -g -O2
    # bp
    /tmp/go-build146765608/bp/_obj/b.o: In function `cb':
    src/bp/b.c:4: undefined reference to `ca'
    collect2: error: ld returned 1 exit status
    Ah, sorry, you're right, I didn't think of that. I don't think there
    is going to be an easy way to do this. You will probably have to move
    your C code into a separate C library used by both Go packages.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedOct 20, '15 at 9:22p
activeOct 20, '15 at 11:17p
posts4
users2
websitegolang.org

2 users in discussion

Billtohara: 2 posts Ian Lance Taylor: 2 posts

People

Translate

site design / logo © 2022 Grokbase