4

I'm trying to build existed Go package into C shared library and header using CGO.

I built the package with -buildmode c-shared as documented.

-buildmode=c-shared
    Build the listed main package, plus all packages it imports,
    into a C shared library. The only callable symbols will
    be those functions exported using a cgo //export comment.
    Requires exactly one main package to be listed

And used //export Func to expose functions as C symbols.

All //export functions in main package are exported properly. However when I moved those functions to sub-package (with //export), those functions are not exported. I imported the sub-package in main package, too.

Here's my code.

main.go

package main

import "C"

import (
    "fmt"
    _ "github.com/onosolutions/archanan-cgo/c"
    "math/rand"
)

// FuncInMain generates a random integer.
//export FuncInMain
func FuncInMain(max C.int) C.int {
    return C.int(rand.Intn(int(max)))
}

func main() {
    fmt.Printf("Hello World %d!\n", int(FuncInMain(256)))
}

c/c.go

package c

import "C"

import (
    "math/rand"
)

// FuncInSubPackage generates a random integer.
//export FuncInSubPackage
func FuncInSubPackage(max C.int) C.int {
    return C.int(rand.Intn(int(max)))
}

Then only FuncInMain is exported.

I read through CGO documentation, but there's nothing saying about exporting in sub-packages. The only clue I got is through go help buildmode, but it said that all imported sub-packages will be compiled. I'm not sure whether it isn't supported or I missed some configurations.

I'd love to achieve that to be able to modularize //export functions.

phuctm97
  • 136
  • 1
  • 9
  • I don't have much experience using CGO, but I'd try importing those packages as dot-imports – Elias Van Ootegem Oct 17 '19 at 13:31
  • @PhucTran Why would `FuncInSubPackage` ever show up as a symbol in the main package? Importing as `_` means it's unused except for initialization side-effects, so there's no way to access the symbols. Go packages are always independent, make a simple pure go proof of concept to see what's going on. – JimB Oct 17 '19 at 13:35
  • @EliasVanOotegem I tried dot imports, it doesn't work either. – phuctm97 Oct 18 '19 at 04:19
  • Got your idea @JimB, I didn't notice the meaning of import as `_`. – phuctm97 Oct 18 '19 at 04:20

1 Answers1

0

Both of them have own C.type, so as far as I know, there's no way to import function with C.type but using linking.

I didn't tried, but give it a chance:

import _ "unsafe"

//go:linkname FuncInSubPackage c.FuncInSubPackage
//export FuncInSubPackage
func FuncInSubPackage(max C.int) C.int
Laevus Dexter
  • 472
  • 4
  • 5
  • It doesn't work. But I understood what you mean, thanks for pointing that out. – phuctm97 Oct 18 '19 at 04:23
  • the main point is that functions can be exported only from "main" package and imported golang's C types are different, so if above one does not work then it's impossible, wrapping or copy paste is required. – Laevus Dexter Oct 21 '19 at 14:25