Skip to content

cmd/cgo: _GoStringLen/_GoStringPtr not available with exported functions in c-archive or c-shared modes #48824

@theimpostor

Description

@theimpostor

What version of Go are you using (go version)?

$ go version
go version go1.17.1 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/shoda/Library/Caches/go-build"
GOENV="/Users/shoda/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/shoda/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/shoda/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.17.1/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.17.1/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17.1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/ct/x2gct7yn2bxfqs891n8h1dxr0000gn/T/go-build205412794=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Using this program:

package main

/*
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void dumpGoString(_GoString_ s) {
    size_t len = _GoStringLen(s);
    const char * sp = _GoStringPtr(s); // may not be NULL terminated
    char * str = strndup(sp, len);
    fprintf(stderr, "go string: %s\n", str);
    free(str);
}
*/
import "C"
import "strconv"

//export PrintWithC
func PrintWithC(v int) {
	C.dumpGoString(strconv.Itoa(v))
}

func main() {
	PrintWithC(42)
}

What did you expect to see?

Doing go build -buildmode=c-archive -o gostring.a main.go should produce a library that is callable from C.

What did you see instead?

❯ go build -buildmode=c-archive -o gostring.a main.go
# command-line-arguments
In file included from _cgo_export.c:4:
main.go:8:18: error: implicit declaration of function '_GoStringLen' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
main.go:9:23: error: implicit declaration of function '_GoStringPtr' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
main.go:9:23: note: did you mean '_GoStringLen'?
main.go:8:18: note: '_GoStringLen' declared here
main.go:9:18: warning: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion]

If I remove the line //export PrintWithC, the app runs fine:

❯ go run main-no-export.go
go string: 42

Also go build -buildmode=c-archive -o gostring.a main-no-export.go succeeds but there is no header file so not sure how I would invoke from C.

Ultimately what I would like to do is to be able to declare void dumpGoString(_GoString_ s); in main.go, build main.go as an archive or shared library, and define dumpGoString in a separate C library which is able to call _GoStringLen and _GoStringPtr on the passed in _GoString_ s from golang. I assumed this was possible from reading the cgo doc, but perhaps I am missing something.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions