使用 ctypes 遍历指针
loop through a pointer with ctypes
我需要在我的 python 应用程序中使用现有的库。这是一个用于读取特定数据文件的库。如果您好奇,可以从这里下载 https://www.hbm.com/en/2082/somat-download-archive/ (somat libsie)。
这个问题跟进了我的 。我能够读取文件,现在我尝试读取的数据是顺序嵌套的……好吧,我不确定我在说什么。
这是头文件的一部分:
# ifdef _WIN32
typedef double sie_float64;
typedef unsigned int sie_uint32;
# else
typedef @sie_float64_type@ sie_float64;
typedef @sie_uint32_type@ sie_uint32;
# endif
[...]
/* At a library user level the internals of these objects are
* unimportant, so we just make them generic pointers. */
typedef void sie_Context;
typedef void sie_File;
typedef void sie_Iterator;
typedef void sie_Test;
typedef void sie_Tag;
typedef void sie_Spigot;
typedef void sie_Output;
typedef void sie_Channel;
typedef void sie_Dimension;
typedef void sie_Histogram;
typedef void sie_Exception;
typedef void sie_Stream;
[...]
#define SIE_OUTPUT_NONE 0
#define SIE_OUTPUT_FLOAT64 1
#define SIE_OUTPUT_RAW 2
SIE_DECLARE(sie_float64 *) sie_output_get_float64(sie_Output *output, size_t dim);
/* > Returns a pointer to an array of float64 (double) data for the
* > specified dimension. This array has a size equal to the number
* > of scans in the output. This is only valid if the type of the
* > dimension is `SIE_OUTPUT_FLOAT64`. The lifetime of the return
* > value is managed by the `sie_Output` object. */
typedef struct _sie_Output_Raw {
void *ptr;
size_t size;
int reserved_1;
} sie_Output_Raw;
SIE_DECLARE(sie_Output_Raw *) sie_output_get_raw(sie_Output *output, size_t dim);
/* > As `sie_output_get_float64`, but for raw data; returns a pointer
* > to an array of sie_Output_Raw for the specified dimension. This
* > array has a size equal to the number of scans in the output. The
* > `ptr` member of the `sie_Output_Raw` struct is a pointer to the
* > actual data, `size` is the size of the data pointed at by `ptr`,
* > in bytes. The lifetime of the return value is managed by the
* > `sie_Output` object. */
typedef struct _sie_Output_Dim {
int type;
sie_float64 *float64;
sie_Output_Raw *raw;
} sie_Output_Dim;
typedef struct _sie_Output_Struct {
size_t num_dims;
size_t num_rows;
size_t reserved_1;
size_t reserved_2;
sie_Output_Dim *dim;
} sie_Output_Struct;
SIE_DECLARE(sie_Output_Struct *) sie_output_get_struct(sie_Output *output);
/* > Returns an `sie_Output_Struct` pointer containing information
* > about the `sie_Output` object. This struct can be used in
* > C-compatible languages to access all data in the `sie_Output`
* > object. The lifetime of the return value is managed by the
* > `sie_Output` object. */
这是他们提供的示例 C 代码的一部分:
#include <sie.h>
[...]
sie_Output_Struct* os;
[...]
/* There are several accessor functions to pull
* properties out of an sie_Output object. */
num_dims = sie_output_get_num_dims(output);
num_rows = sie_output_get_num_rows(output);
printf(" Data block %lu, %lu dimensions, %lu rows:\n",
(unsigned long)sie_output_get_block(output),
(unsigned long)num_dims,
(unsigned long)num_rows);
/* libsie offers several ways to get the data out of
* the output object. One way, more suitable for
* languages that don't have easy access to C structs,
* is to use sie_output_get_float64() and
* sie_output_get_raw() to retrieve an array
* containing one dimension's data.
* sie_output_get_type() returns what kind of data a
* column/dimension contains.
*
* However, in languages that can interpret C structs,
* we can pull out one struct that contains all of the
* data: */
os = sie_output_get_struct(output);
/* Note that this is simply a struct, not an SIE
* object, so we can't call sie_release on it. It is
* owned by the output object and will go away when
* that object does. */
/* Now we can iterate through this C struct, printing
* all the data. */
for (row = 0; row < num_rows; row++) {
printf(" Row %lu: ", (unsigned long)row);
for (dim = 0; dim < num_dims; dim++) {
if (dim != 0)
printf(", ");
switch (os->dim[dim].type) {
/* The type can be SIE_OUTPUT_FLOAT64, or
* SIE_OUTPUT_RAW, as described above. */
case SIE_OUTPUT_FLOAT64:
printf("%.15g", os->dim[dim].float64[row]);
break;
case SIE_OUTPUT_RAW:
/* Raw data has three parts: "ptr", which
* is a pointer to the data; "size", which
* is the size of the data; and "claimed",
* which should be set to 1 if you wish to
* keep the data and clean up the memory
* associated with it yourself. If you
* don't set the "claimed" field, the raw
* data will be cleaned up with the rest
* of the output with the output object
* goes away. */
uchar_p = os->dim[dim].raw[row].ptr;
size = os->dim[dim].raw[row].size;
if (size > 16) {
printf("(raw data of size %lu.)",
(unsigned long)size);
}
else {
for (byte = 0; byte < size; byte++)
printf("%02x", uchar_p[byte]);
}
break;
}
}
printf("\n");
}
这是我的 python 代码:
import ctypes
# Define structures
# typedef @sie_float64_type@ sie_float64;
# typedef @sie_uint32_type@ sie_uint32;
class sie_Output_Raw(ctypes.Structure):
_fields_ = [('ptr', ctypes.c_void_p),
('size', ctypes.c_ulonglong),
('reserved_1', ctypes.c_int)]
class sie_Output_Dim(ctypes.Structure):
_fields_ = [('type', ctypes.c_int),
('sie_float64', ctypes.c_float),
('sie_Output_Raw', ctypes.c_void_p)]
class sie_Output_Struct(ctypes.Structure):
_fields_ = [('num_dims', ctypes.c_ulonglong),
('num_rows', ctypes.c_ulonglong),
('reserved_1', ctypes.c_ulonglong),
('reserved_2', ctypes.c_ulonglong),
#('raw', sie_Output_Dim)]
('sie_Output_Dim', ctypes.c_void_p)]
hllDll = ctypes.WinDLL(r"libsie.dll")
hllDll.sie_context_new.argtypes = ()
hllDll.sie_context_new.restype = ctypes.c_void_p
hllDll.sie_file_open.argtypes = ctypes.c_void_p, ctypes.c_char_p
hllDll.sie_file_open.restype = ctypes.c_void_p
hllDll.sie_get_tests.argtypes = ctypes.c_void_p,
hllDll.sie_get_tests.restype = ctypes.c_void_p
hllDll.sie_iterator_next.argtypes = ctypes.c_void_p,
hllDll.sie_iterator_next.restype = ctypes.c_void_p
hllDll.sie_get_channels.argtypes = ctypes.c_void_p,
hllDll.sie_get_channels.restype = ctypes.c_void_p
hllDll.sie_get_name.argtypes = ctypes.c_void_p,
hllDll.sie_get_name.restype = ctypes.c_char_p
hllDll.sie_spigot_get.argtypes = ctypes.c_void_p,
hllDll.sie_spigot_get.restype = ctypes.c_void_p
hllDll.sie_output_get_struct.argtypes = ctypes.c_void_p,
hllDll.sie_output_get_struct.restype = ctypes.c_void_p
hllDll.sie_output_get_num_dims.argtypes = ctypes.c_void_p,
hllDll.sie_output_get_num_dims.restype = ctypes.c_ulonglong
hllDll.sie_output_get_num_rows.argtypes = ctypes.c_void_p,
hllDll.sie_output_get_num_rows.restype = ctypes.c_ulonglong
hllDll.sie_output_get_float64.argtypes = ctypes.c_void_p, ctypes.c_ulonglong
hllDll.sie_output_get_float64.restype = ctypes.c_ulonglong
context = hllDll.sie_context_new()
file = hllDll.sie_file_open(context, "test.sie".encode('utf-8'))
channel_iterator = hllDll.sie_get_channels(file)
channel = hllDll.sie_iterator_next(channel_iterator)
spigot = hllDll.sie_attach_spigot(channel)
output = hllDll.sie_spigot_get(spigot)
num_dims = hllDll.sie_output_get_num_dims(output)
num_rows = hllDll.sie_output_get_num_rows(output)
os = sie_Output_Struct.from_address(hllDll.sie_output_get_struct(output))
os_dim = sie_Output_Dim.from_address(os.sie_Output_Dim)
这是我得到的,似乎有效:
但是如何获取 C 示例代码中的所有值?
我不是 C 编码员,我不完全理解 os->dim[dim].float64[row]
之类的行中发生的事情,它看起来像是在内存中循环。
我如何在 python 中做到这一点?
我希望我提供了足够的细节。
提前谢谢你。
这是一个工作示例,它访问提到的结构,其中包含关于更正结构定义的注释和遍历结构的 C 代码端口。有我用来验证访问是否正确写入的测试代码。
test.py
import ctypes as ct
SIE_OUTPUT_FLOAT64 = 1
SIE_OUTPUT_RAW = 2
class sie_Output_Raw(ct.Structure):
_fields_ = [('ptr', ct.c_void_p),
('size', ct.c_size_t), # better to use matching type for portability
('reserved_1', ct.c_int)]
class sie_Output_Dim(ct.Structure):
_fields_ = [('type', ct.c_int),
# This is a pointer type, and c_float is 32-bit so use c_double.
# Also fixed structure names to match C.
('float64', ct.POINTER(ct.c_double)),
# Use pointer to structure type since it is known instead of c_void_p.
('raw', ct.POINTER(sie_Output_Raw))]
class sie_Output_Struct(ct.Structure):
_fields_ = [('num_dims', ct.c_size_t),
('num_rows', ct.c_size_t),
('reserved_1', ct.c_size_t),
('reserved_2', ct.c_size_t),
('dim', ct.POINTER(sie_Output_Dim))] # use defined structure pointer
# CDLL/WinDLL are the same on 64-bit, but WinDLL is for 32-bit C function
# using __stdcall calling convention.
# I made a test library for demonstration. See C code below.
hllDll = ct.CDLL(r'./test')
hllDll.sie_output_get_struct.argtypes = ct.c_void_p,
# use defined structure pointer
hllDll.sie_output_get_struct.restype = ct.POINTER(sie_Output_Struct)
os = hllDll.sie_output_get_struct(None) # no need for from_address now
# port of the C code to access the structure.
# Use .contents to dereference a pointer and access the structure.
for row in range(os.contents.num_rows):
for dim in range(os.contents.num_dims):
if dim != 0:
print(', ', end='')
if os.contents.dim[dim].type == SIE_OUTPUT_FLOAT64:
print(f'{os.contents.dim[dim].float64[row]:.15g}', end='')
else:
# Equivalent to casting a C 'void*' to 'unsigned char*'
uchar_p = ct.cast(os.contents.dim[dim].raw[row].ptr, ct.POINTER(ct.c_ubyte))
size = os.contents.dim[dim].raw[row].size
if size > 16:
print(f'(raw data of size {size}.)', end='')
else:
# Slicing a pointer to a particular size creates
# creates a sized list of the array items the
# pointer points to. Result passed to bytes
# for display.
print(bytes(uchar_p[:size]), end='')
print()
test.c - 带有 hard-coded 2x2 输出的测试代码。
#include <stdlib.h>
typedef double sie_float64;
typedef unsigned int sie_uint32;
typedef void sie_Output;
#define SIE_OUTPUT_NONE 0
#define SIE_OUTPUT_FLOAT64 1
#define SIE_OUTPUT_RAW 2
typedef struct _sie_Output_Raw {
void *ptr;
size_t size;
int reserved_1;
} sie_Output_Raw;
typedef struct _sie_Output_Dim {
int type;
sie_float64 *float64;
sie_Output_Raw *raw;
} sie_Output_Dim;
typedef struct _sie_Output_Struct {
size_t num_dims;
size_t num_rows;
size_t reserved_1;
size_t reserved_2;
sie_Output_Dim *dim;
} sie_Output_Struct;
__declspec(dllexport)
sie_Output_Struct* sie_output_get_struct(sie_Output* output) {
sie_Output_Struct* p = malloc(sizeof(sie_Output_Struct));
p->num_dims = 2;
p->num_rows = 2;
p->dim = malloc(2 * sizeof(sie_Output_Dim));
p->dim[0].type = SIE_OUTPUT_FLOAT64;
p->dim[0].float64 = malloc(2 * sizeof(sie_float64));
p->dim[0].raw = NULL;
p->dim[0].float64[0] = 1.5;
p->dim[0].float64[1] = 3.75;
p->dim[1].type = SIE_OUTPUT_RAW;
p->dim[1].float64 = NULL;
p->dim[1].raw = malloc(2 * sizeof(sie_Output_Raw));
p->dim[1].raw[0].ptr = "hello";
p->dim[1].raw[0].size = 5;
p->dim[1].raw[1].ptr = "there";
p->dim[1].raw[1].size = 5;
return p;
}
输出:
1.5, b'hello'
3.75, b'there'
我需要在我的 python 应用程序中使用现有的库。这是一个用于读取特定数据文件的库。如果您好奇,可以从这里下载 https://www.hbm.com/en/2082/somat-download-archive/ (somat libsie)。
这个问题跟进了我的
# ifdef _WIN32
typedef double sie_float64;
typedef unsigned int sie_uint32;
# else
typedef @sie_float64_type@ sie_float64;
typedef @sie_uint32_type@ sie_uint32;
# endif
[...]
/* At a library user level the internals of these objects are
* unimportant, so we just make them generic pointers. */
typedef void sie_Context;
typedef void sie_File;
typedef void sie_Iterator;
typedef void sie_Test;
typedef void sie_Tag;
typedef void sie_Spigot;
typedef void sie_Output;
typedef void sie_Channel;
typedef void sie_Dimension;
typedef void sie_Histogram;
typedef void sie_Exception;
typedef void sie_Stream;
[...]
#define SIE_OUTPUT_NONE 0
#define SIE_OUTPUT_FLOAT64 1
#define SIE_OUTPUT_RAW 2
SIE_DECLARE(sie_float64 *) sie_output_get_float64(sie_Output *output, size_t dim);
/* > Returns a pointer to an array of float64 (double) data for the
* > specified dimension. This array has a size equal to the number
* > of scans in the output. This is only valid if the type of the
* > dimension is `SIE_OUTPUT_FLOAT64`. The lifetime of the return
* > value is managed by the `sie_Output` object. */
typedef struct _sie_Output_Raw {
void *ptr;
size_t size;
int reserved_1;
} sie_Output_Raw;
SIE_DECLARE(sie_Output_Raw *) sie_output_get_raw(sie_Output *output, size_t dim);
/* > As `sie_output_get_float64`, but for raw data; returns a pointer
* > to an array of sie_Output_Raw for the specified dimension. This
* > array has a size equal to the number of scans in the output. The
* > `ptr` member of the `sie_Output_Raw` struct is a pointer to the
* > actual data, `size` is the size of the data pointed at by `ptr`,
* > in bytes. The lifetime of the return value is managed by the
* > `sie_Output` object. */
typedef struct _sie_Output_Dim {
int type;
sie_float64 *float64;
sie_Output_Raw *raw;
} sie_Output_Dim;
typedef struct _sie_Output_Struct {
size_t num_dims;
size_t num_rows;
size_t reserved_1;
size_t reserved_2;
sie_Output_Dim *dim;
} sie_Output_Struct;
SIE_DECLARE(sie_Output_Struct *) sie_output_get_struct(sie_Output *output);
/* > Returns an `sie_Output_Struct` pointer containing information
* > about the `sie_Output` object. This struct can be used in
* > C-compatible languages to access all data in the `sie_Output`
* > object. The lifetime of the return value is managed by the
* > `sie_Output` object. */
这是他们提供的示例 C 代码的一部分:
#include <sie.h>
[...]
sie_Output_Struct* os;
[...]
/* There are several accessor functions to pull
* properties out of an sie_Output object. */
num_dims = sie_output_get_num_dims(output);
num_rows = sie_output_get_num_rows(output);
printf(" Data block %lu, %lu dimensions, %lu rows:\n",
(unsigned long)sie_output_get_block(output),
(unsigned long)num_dims,
(unsigned long)num_rows);
/* libsie offers several ways to get the data out of
* the output object. One way, more suitable for
* languages that don't have easy access to C structs,
* is to use sie_output_get_float64() and
* sie_output_get_raw() to retrieve an array
* containing one dimension's data.
* sie_output_get_type() returns what kind of data a
* column/dimension contains.
*
* However, in languages that can interpret C structs,
* we can pull out one struct that contains all of the
* data: */
os = sie_output_get_struct(output);
/* Note that this is simply a struct, not an SIE
* object, so we can't call sie_release on it. It is
* owned by the output object and will go away when
* that object does. */
/* Now we can iterate through this C struct, printing
* all the data. */
for (row = 0; row < num_rows; row++) {
printf(" Row %lu: ", (unsigned long)row);
for (dim = 0; dim < num_dims; dim++) {
if (dim != 0)
printf(", ");
switch (os->dim[dim].type) {
/* The type can be SIE_OUTPUT_FLOAT64, or
* SIE_OUTPUT_RAW, as described above. */
case SIE_OUTPUT_FLOAT64:
printf("%.15g", os->dim[dim].float64[row]);
break;
case SIE_OUTPUT_RAW:
/* Raw data has three parts: "ptr", which
* is a pointer to the data; "size", which
* is the size of the data; and "claimed",
* which should be set to 1 if you wish to
* keep the data and clean up the memory
* associated with it yourself. If you
* don't set the "claimed" field, the raw
* data will be cleaned up with the rest
* of the output with the output object
* goes away. */
uchar_p = os->dim[dim].raw[row].ptr;
size = os->dim[dim].raw[row].size;
if (size > 16) {
printf("(raw data of size %lu.)",
(unsigned long)size);
}
else {
for (byte = 0; byte < size; byte++)
printf("%02x", uchar_p[byte]);
}
break;
}
}
printf("\n");
}
这是我的 python 代码:
import ctypes
# Define structures
# typedef @sie_float64_type@ sie_float64;
# typedef @sie_uint32_type@ sie_uint32;
class sie_Output_Raw(ctypes.Structure):
_fields_ = [('ptr', ctypes.c_void_p),
('size', ctypes.c_ulonglong),
('reserved_1', ctypes.c_int)]
class sie_Output_Dim(ctypes.Structure):
_fields_ = [('type', ctypes.c_int),
('sie_float64', ctypes.c_float),
('sie_Output_Raw', ctypes.c_void_p)]
class sie_Output_Struct(ctypes.Structure):
_fields_ = [('num_dims', ctypes.c_ulonglong),
('num_rows', ctypes.c_ulonglong),
('reserved_1', ctypes.c_ulonglong),
('reserved_2', ctypes.c_ulonglong),
#('raw', sie_Output_Dim)]
('sie_Output_Dim', ctypes.c_void_p)]
hllDll = ctypes.WinDLL(r"libsie.dll")
hllDll.sie_context_new.argtypes = ()
hllDll.sie_context_new.restype = ctypes.c_void_p
hllDll.sie_file_open.argtypes = ctypes.c_void_p, ctypes.c_char_p
hllDll.sie_file_open.restype = ctypes.c_void_p
hllDll.sie_get_tests.argtypes = ctypes.c_void_p,
hllDll.sie_get_tests.restype = ctypes.c_void_p
hllDll.sie_iterator_next.argtypes = ctypes.c_void_p,
hllDll.sie_iterator_next.restype = ctypes.c_void_p
hllDll.sie_get_channels.argtypes = ctypes.c_void_p,
hllDll.sie_get_channels.restype = ctypes.c_void_p
hllDll.sie_get_name.argtypes = ctypes.c_void_p,
hllDll.sie_get_name.restype = ctypes.c_char_p
hllDll.sie_spigot_get.argtypes = ctypes.c_void_p,
hllDll.sie_spigot_get.restype = ctypes.c_void_p
hllDll.sie_output_get_struct.argtypes = ctypes.c_void_p,
hllDll.sie_output_get_struct.restype = ctypes.c_void_p
hllDll.sie_output_get_num_dims.argtypes = ctypes.c_void_p,
hllDll.sie_output_get_num_dims.restype = ctypes.c_ulonglong
hllDll.sie_output_get_num_rows.argtypes = ctypes.c_void_p,
hllDll.sie_output_get_num_rows.restype = ctypes.c_ulonglong
hllDll.sie_output_get_float64.argtypes = ctypes.c_void_p, ctypes.c_ulonglong
hllDll.sie_output_get_float64.restype = ctypes.c_ulonglong
context = hllDll.sie_context_new()
file = hllDll.sie_file_open(context, "test.sie".encode('utf-8'))
channel_iterator = hllDll.sie_get_channels(file)
channel = hllDll.sie_iterator_next(channel_iterator)
spigot = hllDll.sie_attach_spigot(channel)
output = hllDll.sie_spigot_get(spigot)
num_dims = hllDll.sie_output_get_num_dims(output)
num_rows = hllDll.sie_output_get_num_rows(output)
os = sie_Output_Struct.from_address(hllDll.sie_output_get_struct(output))
os_dim = sie_Output_Dim.from_address(os.sie_Output_Dim)
这是我得到的,似乎有效:
但是如何获取 C 示例代码中的所有值?
我不是 C 编码员,我不完全理解 os->dim[dim].float64[row]
之类的行中发生的事情,它看起来像是在内存中循环。
我如何在 python 中做到这一点?
我希望我提供了足够的细节。 提前谢谢你。
这是一个工作示例,它访问提到的结构,其中包含关于更正结构定义的注释和遍历结构的 C 代码端口。有我用来验证访问是否正确写入的测试代码。
test.py
import ctypes as ct
SIE_OUTPUT_FLOAT64 = 1
SIE_OUTPUT_RAW = 2
class sie_Output_Raw(ct.Structure):
_fields_ = [('ptr', ct.c_void_p),
('size', ct.c_size_t), # better to use matching type for portability
('reserved_1', ct.c_int)]
class sie_Output_Dim(ct.Structure):
_fields_ = [('type', ct.c_int),
# This is a pointer type, and c_float is 32-bit so use c_double.
# Also fixed structure names to match C.
('float64', ct.POINTER(ct.c_double)),
# Use pointer to structure type since it is known instead of c_void_p.
('raw', ct.POINTER(sie_Output_Raw))]
class sie_Output_Struct(ct.Structure):
_fields_ = [('num_dims', ct.c_size_t),
('num_rows', ct.c_size_t),
('reserved_1', ct.c_size_t),
('reserved_2', ct.c_size_t),
('dim', ct.POINTER(sie_Output_Dim))] # use defined structure pointer
# CDLL/WinDLL are the same on 64-bit, but WinDLL is for 32-bit C function
# using __stdcall calling convention.
# I made a test library for demonstration. See C code below.
hllDll = ct.CDLL(r'./test')
hllDll.sie_output_get_struct.argtypes = ct.c_void_p,
# use defined structure pointer
hllDll.sie_output_get_struct.restype = ct.POINTER(sie_Output_Struct)
os = hllDll.sie_output_get_struct(None) # no need for from_address now
# port of the C code to access the structure.
# Use .contents to dereference a pointer and access the structure.
for row in range(os.contents.num_rows):
for dim in range(os.contents.num_dims):
if dim != 0:
print(', ', end='')
if os.contents.dim[dim].type == SIE_OUTPUT_FLOAT64:
print(f'{os.contents.dim[dim].float64[row]:.15g}', end='')
else:
# Equivalent to casting a C 'void*' to 'unsigned char*'
uchar_p = ct.cast(os.contents.dim[dim].raw[row].ptr, ct.POINTER(ct.c_ubyte))
size = os.contents.dim[dim].raw[row].size
if size > 16:
print(f'(raw data of size {size}.)', end='')
else:
# Slicing a pointer to a particular size creates
# creates a sized list of the array items the
# pointer points to. Result passed to bytes
# for display.
print(bytes(uchar_p[:size]), end='')
print()
test.c - 带有 hard-coded 2x2 输出的测试代码。
#include <stdlib.h>
typedef double sie_float64;
typedef unsigned int sie_uint32;
typedef void sie_Output;
#define SIE_OUTPUT_NONE 0
#define SIE_OUTPUT_FLOAT64 1
#define SIE_OUTPUT_RAW 2
typedef struct _sie_Output_Raw {
void *ptr;
size_t size;
int reserved_1;
} sie_Output_Raw;
typedef struct _sie_Output_Dim {
int type;
sie_float64 *float64;
sie_Output_Raw *raw;
} sie_Output_Dim;
typedef struct _sie_Output_Struct {
size_t num_dims;
size_t num_rows;
size_t reserved_1;
size_t reserved_2;
sie_Output_Dim *dim;
} sie_Output_Struct;
__declspec(dllexport)
sie_Output_Struct* sie_output_get_struct(sie_Output* output) {
sie_Output_Struct* p = malloc(sizeof(sie_Output_Struct));
p->num_dims = 2;
p->num_rows = 2;
p->dim = malloc(2 * sizeof(sie_Output_Dim));
p->dim[0].type = SIE_OUTPUT_FLOAT64;
p->dim[0].float64 = malloc(2 * sizeof(sie_float64));
p->dim[0].raw = NULL;
p->dim[0].float64[0] = 1.5;
p->dim[0].float64[1] = 3.75;
p->dim[1].type = SIE_OUTPUT_RAW;
p->dim[1].float64 = NULL;
p->dim[1].raw = malloc(2 * sizeof(sie_Output_Raw));
p->dim[1].raw[0].ptr = "hello";
p->dim[1].raw[0].size = 5;
p->dim[1].raw[1].ptr = "there";
p->dim[1].raw[1].size = 5;
return p;
}
输出:
1.5, b'hello'
3.75, b'there'