LINUX.ORG.RU

Go: вызов функции Go из языка С.

 


0

3

Запилим немного говнокода. Вопросы интеграции Go и C опущены для краткости

//
// Go
//
// Go-функция, у которой нет "//export" и которую я хочу вызвать из C
func call() {
    fmt.Printf("I want to call this Go function from C.")
}

// беру указатель на эту функцию, отдаю её в C
// чтобы C по этому указателю её вызвал.
cb_ptr := unsafe.Pointer( &call )
C.function_c( cb_ptr )
//
// C
//
typedef void (*golang_callback) ();

void function_c(void *_ptr) {
    golang_callback cb = (golang_callback)_ptr;    // cast
    cb();    // crash!
}

Я конечно понимаю, что нормальные люди так не делают.

Но хотелось бы понять разницу в механизме вызова Go-функции из C в случае, когда бы я честно написал //export и вызвал бы её как написано во всех мануалах. В чём физическая низкоуровневая разница, из-за которой у меня всё сегфолтится?

Тебя это не должно волновать. Пиши честно.

Deleted
()

оффтоп

Судя по твоим темам, ты хочешь чего-то странного с Go. Если не секрет, что это и зачем ? :)

joy4eg ★★★★★
()
Ответ на: оффтоп от joy4eg

оффтоп В конечном итоге я хочу десериализовать поток данных кодом C++ в Go-структуру, заранее неизвестную. Засериализовано всё в, скажем, BSON - бинарный JSON. На самом деле не в него, а в мой собственный формат. Ну MessagePack можно сравнить с ним.

Зачем мне C++ — затем, что код работы с этим потоком уже написан, он большой и переписывать его на Go не хочется.

Изнутри C++ сформировать заранее неизвестную Go-структуру нельзя. Да и даже из самого Go тоже — оно же всё компилируемое и статически типизированное. Поэтому пришёл к решению, при котором юзер даёт мне коллбек, а я его дёргаю. Вот пытаюсь дёрнуть заранее неизвестный юзерский коллбек с минимальными издержками. Пока жопа получается - видимо придётся ввести немного издежрек в виде всяких прокси-вызовов.

hlamotron
() автор топика
// беру указатель на эту функцию, отдаю её в C
// чтобы C по этому указателю её вызвал.

Ну, очевидно, что конвенции при вызове не совпадают.

gag ★★★★★
()
Последнее исправление: gag (всего исправлений: 1)
Ответ на: комментарий от hlamotron

Да и даже из самого Go тоже — оно же всё компилируемое и статически типизированное

А как тогда модуль json работает? Смотри модуль reflect.

PolarFox ★★★★★
()
Ответ на: комментарий от PolarFox

А как тогда модуль json работает? Смотри модуль reflect.

А очень просто, ты ему даешь кусок текста, собственно (JSON), и указатель на ... объект. Т.е. оно не создает новых типов данных в runtime.
Ссылка.

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	var jsonBlob = []byte(`[
		{"Name": "Platypus", "Order": "Monotremata"},
		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	]`)
	type Animal struct {
		Name  string
		Order string
	}
	var animals []Animal
	err := json.Unmarshal(jsonBlob, &animals)
	if err != nil {
		fmt.Println("error:", err)
	}
	fmt.Printf("%+v", animals)
}

joy4eg ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.