Go as Glue: Integration with Python, C and Other Languages

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Go is Not an Island, but a Bridge

\n\n

Go is a remarkable language. It's fast, compiled, with an excellent standard library. But let's be honest: in the real world, we rarely write everything from scratch in one language. You have an old, time-tested library in C that you'd hate to rewrite. Or a cool Python script for machine learning. Or you want to run Go logic directly in the browser.

\n

And then the question arises: how to integrate Go with other languages? Don't worry, Go was specifically designed to be a good "neighbor". In this article on PythonLib, we'll break down three main ways to make your Go program friends with foreign code. You'll learn how cgo works, how to call Python functions via system calls, and even how to compile Go into WebAssembly.

\n\n

Go Integration with C via cgo: The Classic Approach

\n\n

The most direct and powerful path is cgo. It's not a library, but a built-in Go mechanism that allows your code to directly call C functions. How does it work? You simply write the import "C" and before it — a comment with C code. The Go compiler will glue it all together.

\n\n

Writing Your First Program with cgo

\n\n

Let's write a simple example: call the standard printf from C. Create a file main.go:

\n\n
package main\n\n/*\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid hello_cgo(const char* name) {\n    printf("Hello from C, %s!\\n", name);\n}\n*/\nimport "C"\nimport "unsafe"\n\nfunc main() {\n    name := C.CString("Gopher")\n    defer C.free(unsafe.Pointer(name))\n    C.hello_cgo(name)\n}\n
\n\n

Run it: go run main.go. If you have GCC installed (or MinGW on Windows), everything will compile. You'll see "Hello from C, Gopher!". Magic!

\n\n

Important: C.CString allocates memory in the C heap, so we must free it via C.free. Otherwise — a leak. Cgo requires discipline from you.

\n\n

Passing Complex Types: Structures

\n\n

Often you need to work not with strings, but with structures. Suppose we have a C library for working with matrices. We want to pass a Go structure into it. Let's do it:

\n\n
package main\n\n/*\ntypedef struct {\n    int x;\n    int y;\n    int result;\n} Point;\n\nPoint add_points(Point a, Point b) {\n    Point r;\n    r.x = a.x + b.x;\n    r.y = a.y + b.y;\n    r.result = r.x + r.y;\n    return r;\n}\n*/\nimport "C"\nimport "fmt"\n\ntype GoPoint struct {\n    X, Y, Result int\n}\n\nfunc main() {\n    a := C.Point{x: 10, y: 20}\n    b := C.Point{x: 30, y: 40}\n    r := C.add_points(a, b)\n\n    goPoint := GoPoint{\n        X:      int(r.x),\n        Y:      int(r.y),\n        Result: int(r.result),\n    }\n    fmt.Printf("Go received: Point{X:%d, Y:%d, Result:%d}\\n", goPoint.X, goPoint.Y, goPoint.Result)\n}\n
\n\n

Notice: we explicitly convert C types to Go types. Cgo cannot automatically map structures, so you are always responsible for the conversion. This is one of the main trade-offs of Go integration with the C language.

\n\n

When cgo is Not Needed

\n

Do not use cgo if:

\n
    \n
  • You just need to call a command in the terminal — use os/exec.
  • \n
  • You are writing cross-platform code — cgo complicates the build.
  • \n
  • Performance is not critical — cgo adds overhead for context switching.
  • \n
\n\n

Go Integration with Python: Scripting Smartly

\n\n

Python and Go are an excellent pair. Go for speed and concurrency, Python for flexibility and ecosystem (NumPy, TensorFlow). How to make them friends? We have two approaches: "heavy" (via cgo and the Python C API) and "light" (via subprocesses).

\n\n

Method 1: Calling Python via os/exec (Simple and Reliable)

\n\n

The safest way for education is to run a Python script as a separate

Blogs

Book Recommendations