2016-09-26 3 views
2

Я могу вызвать функцию Go без параметров с C, per below. Компилируется с помощью go build и гравюрФункция вызова Go со строковым параметром из C?

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; 
} 

Теперь я хочу передать/массив символов строки от C до GoFunction.

Согласно "ссылки C к Go" в cgo documentation это возможно, поэтому я добавить параметр строкового GoFunction и передать массив символов message в 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; 
} 

После go build я получаю эту ошибку:

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

Другие ссылки: https://blog.golang.org/c-go-cgo (не хватает репутации размещать 3 ссылки) Согласно разделу «строки и вещи» в вышеприведенном блоге: «Преобразование между Строки Go и C выполняются с помощью функций C.CString, C.GoString и C.GoStringN. " но они предназначены для использования в Go и не помогают, если я хочу передать строковые данные в Go.

+0

Если вы прочитали документацию, то будет создан '_cgo_export.h', сгенерированный с помощью типа' GoString', который вы можете использовать. Он выглядит так: 'typedef struct {const char * p; GoInt n; } GoString' – JimB

ответ

3

Строка в C является *C.char, а не Go string. Попросите экспортируемая функция принимает правильный тип C, и преобразовать его по мере необходимости в Go:

//export GoFunction 
func GoFunction(str *C.char) { 
    fmt.Println("Hello from GoFunction!") 
    fmt.Println(C.GoString(str)) 
} 
+0

Я думаю, что OP спрашивал, как можно вызвать функцию Go, которая принимает только строки Go. Но я думаю, что создание оберточной функции - это один из способов сделать это. –

+0

@ Ainar-G: хорошая точка, я должен был только дождаться ответа на комментарий;) – JimB

+0

Это работает! Когда я пробовал это при устранении неполадок, я неправильно использовал 'str * C.Char', в результате чего возникла ошибка ' не удалось определить имя имени C.Char' –

2

Если вы хотите передать строку C в функцию, которая принимает только Go строки, вы можете использовать GoString типа на C:

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

Спасибо большое! Я поддержал, но он не будет показан на прилавке, так как я низкий представитель. –

Смежные вопросы