Writing a module for Python with Golang

Source: Internet
Author: User
Tags types of functions
This is a creation in Article, where the information may have evolved or changed.

The introduction module, which needs to be shown in Go C , allows the compiler to support the generation of dynamic-link libraries, and the use of C-language data types in code is critical. Calling Go code from Python code extraction One of the simplest examples

//libadd.gopackage mainimport "C"//export addfunc add(left, right int) int {    return left + right}func main() {}
go build -buildmode=c-shared -o libadd.so libadd.go
from ctypes import cdlllib = cdll.LoadLibrary('./libadd.so')print("Loaded go generated SO library")result = lib.add(2, 3)print(result)

The CGO Export command go doc cgo is documented in, section "C references to Go". Essentially, write //export FUNCNAME before the function definition

There is a passage that requires an explicit comment to //export add expose the Add function to the C call

This thought very simple can use, the interest is full to change the example, changed the simple processing string, but found that cannot run up.

//libadd.gopackage mainimport "C"//export addfunc add(left, right string) string {    return left + right}func main() {}
from ctypes import CDLLlib = CDLL('./libadd.so')print("Loaded go generated SO library")result = lib.add("Hello", "World")print(result)
    • This is the wrong time to run.

      Look at the data again and find this sentence:

The Python code is really short and this are only passing an integer back and forth (more complex string and struct cases a Re much more challenging).

This means that it is not easy to change the string to a string type. This time opened the building PYTHON MODULES with GO 1.5, when the most comprehensive information can be found, unfortunately the process is too complex, the whole idea is to write C code with go, similar Write the interpreter like, to abstract out the Pyobject and then follow the API standard to register, process, return. I just want to be 动态链接库 able to invoke it in a way that can be called.

I began to think about why the use of the type in the example int , I changed to a simple receive string return has string failed. PY is used ctypes to interact with so modules, there is a code translation process Py -> C -> Go , What I can think of is that the processing of the string data type is not the same cause (as it turns out I guess). So think about it, what type of string in the Py is passed to go and what types are used to receive it? Read a lot of information, all the answers in the Python DOC official website about the ctypes module can be found. Let's take a look at this picture:


001.png


Here you can see clearly the ctypes string in Python3 bytes and the string corresponding two pointer types. also provides argtypes and restype to explicitly convert the parameters and return types of functions in a dynamic-link library. ( Reference StackOverflow)

At this time, follow the thought process to modify the code

//libadd.gopackage mainimport "C"//export addfunc add(left, right *C.char) *C.char {      // bytes对应ctypes的c_char_p类型,翻译成C类型就是 char *指针      merge := C.GoString(left) + C.GoString(right)    return C.CString(merge)}func main() {}

Re-compiling

go build -buildmode=c-shared -o libadd.so libadd.go

Referenced in Python

import ctypesadd = ctypes.CDLL('./libadd.so').add# 显式声明参数和返回的期望类型add.argtypes = [ctypes.c_char_p, ctypes.c_char_p]add.restype = ctypes.c_char_pleft = b"Hello"right = b"World"print(add(left, right))

Correct output Result:

b"HelloWorld"

In this way, a basic module is completed, as long as the input parameters and return the results of the data type processing, I only need to enrich the function of the processing logic, the Go module in the function of the internal implementation of Python is transparent, as long as the parameters are correct. More information about CGO, You can check golang.org for yourself.

Summarize

    1. The parameter transfer between Python and go, which needs to be converted to the corresponding C type when handling non-int
    2. cTYPES needs to explicitly declare the parameters of the DLL function and return the expected data type
    3. Note the difference between strings bytes and string in Python3
    4. The Go module needs to //export declare an externally callable
    5. The type of Go processing C is required to be explicitly converted
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.