Re: Using Go to build a shared library to be called from C

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 14, 2011 at 1:24 AM, Ian Lance Taylor <iant@xxxxxxxxxx> wrote:
> LRN <lrn1986@xxxxxxxxx> writes:
>
>> However, if i put anything more complex than "return 1" into Myfunc in
>> Go (such as using fmt.Printf() or returning a string - with
>> appropriate prototype changes to 'string' and 'char*' in Go and C,
>> naturally), it segfaults at runtime.
>>
>> Is that a limitation of gccgo, a bug, or am i simply doing something wrong?
>
> This is a current limitation of gccgo.  At present nothing initializes
> the packages imported by a packaged compiled into a shared library.
> This is fixable with a bit of thought but is not high on the priority
> list.
How's it going? Any news.

As a side note, after discussing [1] static linking in Go (due to the
fact that go doesn't have dynamic linking), i thought a bit, and came
up with this:

---------main_shared.go
package main_shared

import (
	"fmt"
)

func Myfunc () string {
	return "result"
}

type ComplexType struct {
	somestring string
	someint int
}

func Myfunc2 (n int) (r ComplexType) {
	r.somestring = fmt.Sprintf ("a formatted version of integer %d", n)
	r.someint = n
	return
}
---------end of main_shared.go

---------main_executable.go
package main

import (
	"fmt"
)

func myfunc () string __asm__ ("go.main_shared.Myfunc")

type ComplexType struct {
	somestring string
	someint int
}

func myfunc2 (n int) (r ComplexType) __asm__ ("go.main_shared.Myfunc2")

func main() {
   s := myfunc ()
	fmt.Printf ("Calling myfunc() resulted in a string %s\n", s)
   n := 5
   c := myfunc2 (n)
	fmt.Printf ("Passing %d to myfunc2() resulted in %s (with an integer
%d)\n", n, c.somestring, c.someint)
}
---------end of main_executable.go

compile and run:
gccgo -g -O0 -fPIC -shared main_shared.go -o libmain_shared.so -lgcc
gccgo -g -O0 main_executable.go -o main -L. -lmain_shared
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main

and it prints:
Calling myfunc() resulted in a string result
Passing 5 to myfunc2() resulted in a formatted version of integer 5
(with an integer 5)

Which was expected.

ldd says that the executable is linked to libgo and libmain_shared:

$ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ldd ./main
	linux-vdso.so.1 =>  (0x00007fff9022b000)
	libmain_shared.so => ./libmain_shared.so (0x00007f0e4a7fa000)
	libgo.so.0 => /usr/lib/x86_64-linux-gnu/libgo.so.0 (0x00007f0e49bb7000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0e49934000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0e4971e000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0e4939a000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f0e4a9ff000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0e4917d000)

I thought that since the problem lies in libgo not being initializing,
then it should work with the main executable written in Go, because it
does initialize its own runtime library, which is then shared with
libmain_shared.

My guess is that this will only work when both modules are linked to
the same version of libgo.

Are there any other problems with this kind of linking?

Is it ever going to be a valid way of linking Go modules, or just a hack?

Also, it really makes me think about putting ComplexType definition
into separate file and calling it a "header" ... weird.

P.S. This time it didn't work without -fPIC for some reason.

[1] http://comments.gmane.org/gmane.comp.lang.go.general/41770



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux