Comments 23
UFO just landed and posted this here
Спасибо за статью, еще бы пункт "Из PHP" — цены бы не было))
+2
UFO just landed and posted this here
UFO just landed and posted this here
Вообще go крутой язык
-4
КДПВ супер. А мне вот интересно, можно ли таки образом сделать библиотеку для С++ с легковесными горутинами внутри и скажем вызовом через cgo переданных std::function
0
Но зачем?
0
Ради планировщика go https://habrahabr.ru/company/ua-hosting/blog/269271/
-2
Вызов функции через cgo с ненулевой вероятностью создаст новый полноценный thread операционной системы, что убьёт всю лёгкость горутин.
0
UFO just landed and posted this here
Ну или как вариант вдруг все таки к C++20 стандарту примут корутины. Шанс вроде есть https://habrahabr.ru/company/yandex/blog/323972/
0
По опыту экспериментов с этим на Ruby, можно легко создавать в go коде gorutines, но надо дожидаться когда они завершатся, иначе будет segfault в конце. При этом прокинуть туда callback нельзя, видимо GIL и всякая другая обвязка над Ruby блоками не позволяет вызвать их. Вот на toster задавал еще тогда вопрос.
0
какое то «щиворот на выворот», обычно из go вызывают C/C++ методы
0
По мне в Ruby лучше написать нативное расширение, без динамической загрузки и поинтеров в ruby коде.
Минус FFI в том, что если выскакивает Exception в C, то все сразу падает, а в расширении хоть можно код обернуть и поймать ошибку и ничего не упадает.
Минус FFI в том, что если выскакивает Exception в C, то все сразу падает, а в расширении хоть можно код обернуть и поймать ошибку и ничего не упадает.
+2
Надо отметить, что я аналогичную задачу делал для Python, и при этом функция из библиотеки вызывалась как родная функция Python, без всяких cffi и с обработкой Python исключений. Но в целом статья хорошая.
0
Вызов Go методов из других языков разжеван уже донельзя. Вы бы лучше рассказали как там дела обстоят с возвращаемыми значениями (а здесь и начинаются настоящие приключения). Все работает очень гладко до тех пор пока мы не попробуем вернуть что-то посложнее строк или int.
Например вызывать метод Go из С++ и возвращать сложную структуру в теории нужно в такой последовательности:
1. В С++ аллоцировать структуру
2. Передать в Go поинтер
3. В Go заполнить значения структуры через C.types и unsafe.Pointer
4. В С++ проверить заполненность
И при этом очень легко нарваться на segfault.
А теперь представим что вместо вызова С -> Go, нам нужно вызвать Go -> С. Все становится еще веселее:
1. В Go (через CGo) нужно аллоцировать структуру (через написание отдельной функции в отдельном файле) и вернуть поинтер на нее.
2. В Go заполнить структуру через C.types и unsafe.Pointer
3. Передать unsafe.Pointer в C++
4. Скомпилировать эту матрешку (Go -> CGo -> Go -> C)
При этом шанс получить segfault возрастает экспоненциально.
А вся проблема в том что Go runtime любит очень быстро подчищать память. И если мы передали структуру собранную в Go напрямую, примерно на 2й инструкции в С она уже будет подчищена.
Например вызывать метод Go из С++ и возвращать сложную структуру в теории нужно в такой последовательности:
1. В С++ аллоцировать структуру
2. Передать в Go поинтер
3. В Go заполнить значения структуры через C.types и unsafe.Pointer
4. В С++ проверить заполненность
И при этом очень легко нарваться на segfault.
А теперь представим что вместо вызова С -> Go, нам нужно вызвать Go -> С. Все становится еще веселее:
1. В Go (через CGo) нужно аллоцировать структуру (через написание отдельной функции в отдельном файле) и вернуть поинтер на нее.
2. В Go заполнить структуру через C.types и unsafe.Pointer
3. Передать unsafe.Pointer в C++
4. Скомпилировать эту матрешку (Go -> CGo -> Go -> C)
При этом шанс получить segfault возрастает экспоненциально.
А вся проблема в том что Go runtime любит очень быстро подчищать память. И если мы передали структуру собранную в Go напрямую, примерно на 2й инструкции в С она уже будет подчищена.
+2
Вызывать то можно, но производительность при это не очень.
0
Sign up to leave a comment.
Вызов функций Go из других языков