-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/cgo: _GoStringLen/_GoStringPtr not available with exported functions in c-archive or c-shared modes #48824
Comments
Also, if I forward-declare package main
/*
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
size_t _GoStringLen(_GoString_ s);
const char *_GoStringPtr(_GoString_ s);
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)
}
|
The I think that means that no, these symbols will not be available as part of a |
Quoting https://golang.org/cmd/cgo:
You have a definition in your C preamble, and that is not supported when using |
Thanks, you are correct. Ultimately I think I was able to get this work by:
Seems like 2 would be good to mention in the cgo documentation, and 3 should be done automatically? Here is what I ended up with, which allows me to access a Go string from C with no extra allocations: main.go: package main
/*
#cgo linux LDFLAGS: -Wl,-unresolved-symbols=ignore-all
#cgo darwin LDFLAGS: -Wl,-undefined,dynamic_lookup
extern void dumpCString(const char *s, size_t length);
size_t _GoStringLen(_GoString_ s);
const char *_GoStringPtr(_GoString_ s);
static inline void dumpGoString(_GoString_ s)
{
dumpCString(_GoStringPtr(s), _GoStringLen(s));
}
*/
import "C"
import "strconv"
//export PrintWithC
func PrintWithC(v int) {
C.dumpGoString(strconv.Itoa(v))
}
func main() {
PrintWithC(42)
} main.c: #include <stdio.h>
#include "libgostring.h"
void dumpCString(const char *s, size_t length)
{
printf("go string: %.*s\n", (int)length, s);
}
int
main(int argc, char** argv)
{
PrintWithC(42);
}
|
As far as I can tell |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Using this program:
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?
If I remove the line
//export PrintWithC
, the app runs fine: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 definedumpGoString
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.The text was updated successfully, but these errors were encountered: