6

I can call a Go function without parameters from C, per below. This compiles via go build and prints

Hello from Golang main function!
CFunction says: Hello World from CFunction!
Hello from GoFunction!

main.go

package main

//extern int CFunction();
import "C"
import "fmt"

func main() {
  fmt.Println("Hello from Golang main function!")
  //Calling a CFunction in order to have C call the GoFunction
  C.CFunction();
}

//export GoFunction
func GoFunction() {
  fmt.Println("Hello from GoFunction!")
}

file1.c

#include <stdio.h>
#include "_cgo_export.h"

int CFunction() {
  char message[] = "Hello World from CFunction!";
  printf("CFunction says: %s\n", message);
  GoFunction();
  return 0;
}

Now, I want to pass a string/char array from C to GoFunction.

According to "C references to Go" in the cgo documentation this is possible, so I add a string parameter to GoFunction and pass the char array message to GoFunction:

main.go

package main

//extern int CFunction();
import "C"
import "fmt"

func main() {
  fmt.Println("Hello from Golang main function!")
  //Calling a CFunction in order to have C call the GoFunction
  C.CFunction();
}

//export GoFunction
func GoFunction(str string) {
  fmt.Println("Hello from GoFunction!")
}

file1.c

#include <stdio.h>
#include "_cgo_export.h"

int CFunction() {
  char message[] = "Hello World from CFunction!";
  printf("CFunction says: %s\n", message);
  GoFunction(message);
  return 0;
}

Upon go build I receive this error:

./file1.c:7:14: error: passing 'char [28]' to parameter of incompatible type 'GoString'
./main.go:50:33: note: passing argument to parameter 'p0' here

According to the "strings and things" section of the above "C? Go? Cgo!" blog post:

Conversion between Go and C strings is done with the C.CString, C.GoString, and C.GoStringN functions.

But these are for use in Go, and not helpful if I want to pass string data into Go.

1
  • If you read the documentation under that, there will be a _cgo_export.h generated with the type GoString which you can use. It looks like: typedef struct { const char *p; GoInt n; } GoString Commented Sep 26, 2016 at 17:44

2 Answers 2

8

A string in C is a *C.char, not a Go string. Have your exported function accept the correct C type, and convert it as necessary in Go:

//export GoFunction
func GoFunction(str *C.char) {
    fmt.Println("Hello from GoFunction!")
    fmt.Println(C.GoString(str))
}
Sign up to request clarification or add additional context in comments.

4 Comments

I think OP was asking, how can one call a Go function that only accepts Go strings. But I guess creating a wrapper function is one way to do it.
@Ainar-G: good point, I should have have just waited for the comment reply ;)
This works! When I tried this while troubleshooting I incorrectly used str *C.Char, resulting in the error could not determine kind of name for C.Char
@JoePrvacy See my answer if you actually need str to be string.
6

If you want to pass a C string to a function that accepts only Go strings, you can use GoString type on the C side:

char message[] = "Hello World from CFunction!";
printf("CFunction says: %s\n", message);
GoString go_str = {p: message, n: sizeof(message)}; // N.B. sizeof(message) will
                                                    // only work for arrays, not
                                                    // pointers.
GoFunction(go_str);
return 0;

1 Comment

Thanks much! I upvoted but it won't show on the counter since I am low rep.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.