DEV Community

David Sugar
David Sugar

Posted on

Go and C, friends forever?

As there are no actively maintained complete sip stack in Go, and most development seems to have died years ago, I had started to adapt libeXosip2 for use with Go. Doing the more real-time side in pure C, which Go can directly call and wrap using cgo, and the squishy upper level logic in Go, can make sense to me. I could also see writing a RTP stack operating in pure C with it's own C threads, to call from Go in the same way.

The downside of wrapping C in Go is that really you need to convert everything to Go types and structs, especially to export them, and to do so efficiently, all the C wrapper code should really be together in one Go file, along with the C headers and stubs you make. This is not a big deal for simpler C libs, and libeXosip2 mostly deals with int and string types, so that is not too bad, but it does have an event struct that has complicated internal C types. A new Go event struct would have to be made, and all these internals converted, in the Go wrapper file, too.

In C++, I can just carry the libeXosip2 event struct as is, and decode parts of it in different places as needed. But C++ imposes different problems, so while I have a rather thin libeXosip2 wrapper in C++, complexity is scattered throughout the codebase. Other kinds of complexity of course include building C++ projects, and CMake introduces as many problems as it solves.

Structurally Go makes a lot of sense for server logic for the kinds of applications I do. Event objects would move thru Go channels to different subsystems where they would be processed. This is kind of what Coventry already does in C++ with a homemade micro-actor framework. Those that work with Ruby would recognize this as being like creating a domain specific language. A lot of code is required to "tame" cpp in this way. I used to do this in GNU Common C++, and now use my own header-only C++ libs, as it's less work and much easier to use C++ type deduction when everything is header-only. The common patterns I often use are already much more naturally expressed in Go as is. So Go offers, for me, a tradeoff between a maintaining a complex C wrapper or complex C++ language enhancements. The remaining server code feels simpler and easier to maintain in Go.

Top comments (0)