This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


LRN <lrn1986@gmail.com> writes:

> On Tue, Jun 14, 2011 at 1:24 AM, Ian Lance Taylor <iant@google.com> wrote:
>> LRN <lrn1986@gmail.com> 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.

The status is unchanged.


> 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.

Yes, it should work in that case, I think.  I have not actually tried
it, though.


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

There will probably be a way to dynamically link Go modules at some
point, but I don't know when.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]