How to Fix Python‑ctypes Return Value Errors When Calling Go Libraries

This article explains why Python's ctypes returns incorrect values when invoking Go-compiled shared libraries, shows how to map C types correctly, and provides step‑by‑step code examples for handling both integer and string return values using proper restype declarations.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
How to Fix Python‑ctypes Return Value Errors When Calling Go Libraries

1. Introduction

In a previous article we called Go code from Python using a compiled .so file, which improved performance but produced unexpected return values. This follow‑up investigates the cause and presents a complete solution.

2. Why Return Value Errors Occur

The problem originates from the .h header generated by the Go compiler. It defines C‑compatible types for Go functions, and the default ctypes mapping does not match these definitions, especially for long long values.

3. ctypes Type Mapping Table

ctypes type   C type                Python type
c_bool       _Bool                 bool (1)
c_char       char                  1‑character bytes object
c_wchar      wchar_t               1‑character string
c_byte       char                  int
c_ubyte      unsigned char         int
c_short      short                 int
c_ushort     unsigned short        int
c_int        int                   int
c_uint       unsigned int          int
c_long       long                  int
c_ulong      unsigned long         int
c_longlong   __int64 or long long  int
c_ulonglong  unsigned __int64 or unsigned long long  int
c_size_t     size_t                int
c_ssize_t    ssize_t or Py_ssize_t int
c_float      float                 float
c_double     double                float
c_longdouble long double           float
c_char_p     char * (NUL terminated) bytes object or None
c_wchar_p    wchar_t * (NUL terminated) string or None
c_void_p     void *                int or None

4. Handling Integer Return Values

Using the table, we map Go's long long to c_longlong and define a Structure with a single field.

from ctypes import *
import time

class StructPointer(Structure):
    _fields_ = [("p", c_longlong,)]

if __name__ == '__main__':
    begin = time.time()
    s = CDLL("s1.so")
    s.run.restype = StructPointer
    result = s.run(100000000)
    print("result:", result.p)
    print("elapsed:", time.time() - begin)

The output now matches the Go calculation.

5. Handling String Return Values

When a Go function returns a string, the generated header shows a struct _GoString_ containing a pointer and a length. We map it to a Structure with c_char_p and c_longlong.

class StrPointer(Structure):
    _fields_ = [("p", c_char_p), ("n", c_longlong)]

s.speak.restype = StrPointer
speak = s.speak()
text = str(speak.p[:speak.n], encoding="utf-8")
print("speak:", text)

The program prints the correct Chinese string returned from Go.

6. Conclusion

By correctly mapping C types to ctypes structures and setting restype, both integer and string return values from Go can be retrieved accurately in Python. This resolves the major interoperability pitfalls when using Python to call Go code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonGoShared LibraryInteroperabilitycgoctypes
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.