Python Ctypes传递在.h文件中定义的结构指针。

Python Ctypes传递在.h文件中定义的结构指针。,python,c,pointers,struct,ctypes,Python,C,Pointers,Struct,Ctypes,我对ctypes和C都是新手,在通过ctypes将结构指针变量传递到python中调用的C函数时遇到问题。请容忍我,如果它太基本和明显。 下面是我的c代码的样子 #include "mylib.h" (inside this mylib.h file MYSTRUCT is defined) struct MYSTRUCT* modifystruct(a,b,c,d,e) { MYSTRUCT *mystpointer; ..... ..... return mystpointer; }

我对ctypes和C都是新手,在通过ctypes将结构指针变量传递到python中调用的C函数时遇到问题。请容忍我,如果它太基本和明显。 下面是我的c代码的样子

#include "mylib.h"   (inside this mylib.h file MYSTRUCT is defined)

struct MYSTRUCT* modifystruct(a,b,c,d,e)
{
MYSTRUCT *mystpointer;
.....
.....
return mystpointer;
} 


int mycfunction(mystpointer)
MYSTRUCT *mystpointer;
{
.........
.........
.........
}
与上面一样,modifystruct函数update*mystpointer是指向MYSTRUCT并返回它的指针。 MyCfFunction是传递返回的mystpointer。在C语言中,这在主函数中运行良好。 但是,当我尝试使用ctypes将“.so”文件加载到python中时,它失败了,并且我认为我没有正确定义mystpointer的argtype。 下面是我编写的简短python代码。假设上面的c代码被编译为“mycmodule.so”

在C代码中,我必须将mystpointer类型定义为“MYSTRUCT*mystpointer
然而,我不知道如何在ctypes中这样做。。。相反,我将这些类型定义为c_void_p,但这会触发失败。提前谢谢

我认为您可能缺少的是确切地知道要将结构内存分配到哪里。下面的c代码提供了一个为结构分配内存并返回指向它的指针(new_struct())的函数

#包括
#包括
#包括
类型定义结构{
INTA;
int b;
}我的结构;
我的结构*新结构()
{
my_struct*struct_instance=(my_struct*)malloc(sizeof(my_struct));
memset(struct_instance,0,sizeof(my_struct));
返回struct_实例;
}
int modify_struct(my_struct*ms){
ms->a=1;
ms->b=2;
返回0;
}
无效打印结构(我的结构*ms){
printf(“我的结构{\n”
“a=%d\n”
“b=%d\n”
“}\n”,ms->a,ms->b);
}
从Python中,为了获得指针,调用进行分配的C函数,然后您可以将其传递给将其作为参数的其他C函数

import ctypes

lib_file_path = <<< path to lib file >>>

# Very simple example of how to declare a ctypes structure to twin the
# C library's declaration. This doesn't need to be declared if the Python
# code isn't going to need access to the struct's data members.
class MyStruct(ctypes.Structure):
    _fields_ = [('a', ctypes.c_int),
                ('b', ctypes.c_int)]

def print_struct(s):
    # Print struct that was allocated via Python ctypes.
    print("my_struct.a = %d, my_struct.b = %d" % (s.a, s.b))

def print_struct_ptr(sptr):
    # Print pointer to struct. Note the data members of the pointer are 
    # accessed via 'contents'.
    print("my_struct_ptr.contents.a = %d, my_struct_ptr.contents.b = %d" 
          % (sptr.contents.a, sptr.contents.b))


my_c_lib = ctypes.cdll.LoadLibrary(lib_file_path)

# If you don't need to access the struct's data members from Python, then 
# it's not necessary to declare MyStruct above. Also, in that case,
# 'restype' and 'argtypes' (below) can be set to ctypes.c_void_p instead.
my_c_lib.new_struct.restype     =  ctypes.POINTER(MyStruct)
my_c_lib.modify_struct.argtypes = [ctypes.POINTER(MyStruct)]

# Call C function to create struct instance.
my_struct_c_ptr = my_c_lib.new_struct()
print_struct_ptr(my_struct_c_ptr)

my_c_lib.modify_struct(my_struct_c_ptr)
print_struct_ptr(my_struct_c_ptr)

# Allocating struct instance from Python, then passing to C function.
my_struct_py = MyStruct(0, 0)
print_struct(my_struct_py)

my_c_lib.modify_struct(ctypes.byref(my_struct_py))
print_struct(my_struct_py)

# Data members of Python allocated struct can be acessed directly.
my_struct_py.a = 555

my_c_lib.print_struct_c(ctypes.byref(my_struct_py)) # Note use of 'byref()'
                                                    # to invoke c function.
导入ctypes
库文件路径=>
#非常简单的示例,说明如何声明ctypes结构以使
#C图书馆的声明。如果Python
#代码不需要访问结构的数据成员。
类MyStruct(ctypes.Structure):
_字段\=[('a',ctypes.c_int),
('b',ctypes.c_int)]
def打印结构:
#打印通过Python ctypes分配的结构。
打印(“我的结构a=%d,我的结构b=%d”%(s.a,s.b))
def打印结构ptr(sptr):
#打印指向结构的指针。注意指针的数据成员是
#通过“内容”访问。
打印(“my_struct_ptr.contents.a=%d,my_struct_ptr.contents.b=%d”
%(sptr.contents.a,sptr.contents.b))
my_c_lib=ctypes.cdll.LoadLibrary(lib_file_路径)
#如果不需要从Python访问结构的数据成员,那么
#没有必要在上面声明我的结构。而且在这种情况下,,
#“restype”和“argtypes”(如下)可以改为ctypes.c_void_p。
my_c_lib.new_struct.restype=ctypes.POINTER(MyStruct)
my_c_lib.modify_struct.argtypes=[ctypes.POINTER(MyStruct)]
#调用C函数创建结构实例。
my_struct_c_ptr=my_c_lib.new_struct()
打印结构图(我的结构图)
my_c_lib.modify_struct(my_struct_c_ptr)
打印结构图(我的结构图)
#从Python中分配struct实例,然后传递给C函数。
my_struct_py=MyStruct(0,0)
打印结构(我的结构)
my_c_lib.modify_struct(ctypes.byref(my_struct_py))
打印结构(我的结构)
#Python分配结构的数据成员可以直接访问。
my_struct_py.a=555
my_c_lib.print_struct_c(ctypes.byref(my_struct_py))#注意使用'byref()'
#调用c函数。

上面的代码已经更新,包含了如何通过Python分配结构实例的示例,以及如何访问C分配的或Python分配的结构的数据成员(请注意打印函数中的差异)。

请发布a。在C中,modifystruct()的代码中没有声明参数类型。。。除此之外,结构在哪里被分配?例如,除了modifystruct()之外,还有其他C函数返回指向结构的指针吗?或者您正试图通过Python代码为结构分配内存?检查。谢谢提示!我试过你的例子。我能够运行(int-mycfunction(mystpointer))函数,但它并没有给出正确的结果。您能分享一下如何从Python中分配、访问结构吗?更新了更多示例。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int a;
    int b;
} my_struct;

my_struct *new_struct()
{
    my_struct *struct_instance = (my_struct *)malloc(sizeof(my_struct));
    memset(struct_instance, 0, sizeof(my_struct));
    return struct_instance;
}

int modify_struct(my_struct *ms) {
    ms->a = 1;
    ms->b = 2;
    return 0;
}

void print_struct_c(my_struct *ms) {
    printf("my_struct {\n"
           "    a = %d\n"
           "    b = %d\n"
           "}\n", ms->a, ms->b);
}
import ctypes

lib_file_path = <<< path to lib file >>>

# Very simple example of how to declare a ctypes structure to twin the
# C library's declaration. This doesn't need to be declared if the Python
# code isn't going to need access to the struct's data members.
class MyStruct(ctypes.Structure):
    _fields_ = [('a', ctypes.c_int),
                ('b', ctypes.c_int)]

def print_struct(s):
    # Print struct that was allocated via Python ctypes.
    print("my_struct.a = %d, my_struct.b = %d" % (s.a, s.b))

def print_struct_ptr(sptr):
    # Print pointer to struct. Note the data members of the pointer are 
    # accessed via 'contents'.
    print("my_struct_ptr.contents.a = %d, my_struct_ptr.contents.b = %d" 
          % (sptr.contents.a, sptr.contents.b))


my_c_lib = ctypes.cdll.LoadLibrary(lib_file_path)

# If you don't need to access the struct's data members from Python, then 
# it's not necessary to declare MyStruct above. Also, in that case,
# 'restype' and 'argtypes' (below) can be set to ctypes.c_void_p instead.
my_c_lib.new_struct.restype     =  ctypes.POINTER(MyStruct)
my_c_lib.modify_struct.argtypes = [ctypes.POINTER(MyStruct)]

# Call C function to create struct instance.
my_struct_c_ptr = my_c_lib.new_struct()
print_struct_ptr(my_struct_c_ptr)

my_c_lib.modify_struct(my_struct_c_ptr)
print_struct_ptr(my_struct_c_ptr)

# Allocating struct instance from Python, then passing to C function.
my_struct_py = MyStruct(0, 0)
print_struct(my_struct_py)

my_c_lib.modify_struct(ctypes.byref(my_struct_py))
print_struct(my_struct_py)

# Data members of Python allocated struct can be acessed directly.
my_struct_py.a = 555

my_c_lib.print_struct_c(ctypes.byref(my_struct_py)) # Note use of 'byref()'
                                                    # to invoke c function.