Home > Enterprise >  How to access multiple return values in restype?
How to access multiple return values in restype?

Time:01-03

I am writing a Go program like the below:

package main

import (
    "C"
)

//export getData
func getData(symbol string, day string, month string, year string) (string, string) {
    return "A", "B"
}

func main() {

}

In Python, I am doing this:

import ctypes
library = ctypes.cdll.LoadLibrary('./deribit.so')
get_data = library.getData

# Make python convert its values to C representation.
get_data.argtypes = [ctypes.c_wchar, ctypes.c_wchar,ctypes.c_wchar,ctypes.c_wchar]
get_data.restype = [ctypes.c_wchar,ctypes.c_wchar]

d,c = get_data("symbol", "day","month","year")
print(d,c)

And it gives the error:

  get_data.restype = ctypes.c_wchar,ctypes.c_wchar
TypeError: restype must be a type, a callable, or None

CodePudding user response:

From the cgo docs:

Go functions can be exported for use by C code in the following way:

//export MyFunction
func MyFunction(arg1, arg2 int, arg3 string) int64 {...}

//export MyFunction2
func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...}

They will be available in the C code as:

extern GoInt64 MyFunction(int arg1, int arg2, GoString arg3);
extern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);

found in the _cgo_export.h generated header, after any preambles copied from the cgo input files. Functions with multiple return values are mapped to functions returning a struct.

A function that returns multiple values gets mapped to a function returning a struct. Read the _cgo_export.h generated header to see the struct definition; the documentation is unclear on what the struct definition looks like. I would guess it just contains all return values in the order the function returns them, with some unspecified auto-generated names, but the documentation doesn't say.

(GoString in the above code should probably say _GoString_; this is the only part of the linked documentation page that writes GoString without underscores. It's probably an error.)


However, you have other problems, both of which will prevent you from calling your getData function.

The first problem is that a Go string is not a char *. It is its own separate type. C code can interact with Go strings through the _GoString_ type and several helper functions, but creating Go strings from outside Go is unsupported.

The second is that due to Go garbage collection, there are many restrictions on how non-Go code is allowed to interact with pointers to Go memory. One of the restrictions is that Go code cannot return Go strings to non-Go code, or return anything else that contains pointers to Go memory. Your getData returns Go strings, so it cannot be called from outside Go.

  • Related