簡體   English   中英

如何在python中通過C函數操作C類型指針返回?

[英]How to operate C type pointer return by C function in python?

這是“ Testlib.c”中的C代碼。 我只是從C函數返回一個指向結構的指針。 並且所有的C代碼都將編譯為lib,供python調用。

#include <stdio.h>
#include <stdlib.h>
typedef struct{
    int num;
    char c;
}aStruct;
aStruct* newStructPointer()
{
    aStruct* s = (aStruct*)malloc(sizeof(aStruct)) ;
    s->num = 3;
    s->c = 'f';
    return s;
}
int getNumField(aStruct* a)
{
    return a->num;
}
char getCharField(aStruct* a)
{
    return a->c;
}

這是Python代碼。 這很簡單,調用newStructPointer來獲取新的結構,然后在其字段中獲取數字值。

#!/usr/bin/env python
# -*- coding: utf-8 -*- 
from ctypes import *
class testlib(object):
    def __init__(self):
        lib=cdll.LoadLibrary("libtestdylib.dylib")
        s=lib.newStructPointer()
        num=lib.getNumField(cast(s, c_void_p))

t=testlib()

然后,由於指針已經無效而崩潰,這是崩潰報告:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libtestdylib.dylib              0x000000010638ef5c getNumField + 12 (interface.c:26)
1   libffi.dylib                    0x00007fff9354ef9c ffi_call_unix64 + 76
2   libffi.dylib                    0x00007fff9354f78e ffi_call + 790
3   _ctypes.so                      0x000000010637390e _ctypes_callproc + 794
4   _ctypes.so                      0x000000010636df80 0x10636b000 + 12160
5   org.python.python               0x0000000106085f72 PyObject_Call + 101
6   org.python.python               0x00000001060ffdf5 PyEval_EvalFrameEx + 15416
7   org.python.python               0x00000001060fc093 PyEval_EvalCodeEx + 1641
8   org.python.python               0x00000001060a3796 0x10607c000 + 161686
9   org.python.python               0x0000000106085f72 PyObject_Call + 101
10  org.python.python               0x00000001060909a7 0x10607c000 + 84391
11  org.python.python               0x0000000106085f72 PyObject_Call + 101
12  org.python.python               0x00000001060cb6ce 0x10607c000 + 325326
13  org.python.python               0x00000001060c7184 0x10607c000 + 307588
14  org.python.python               0x0000000106085f72 PyObject_Call + 101
15  org.python.python               0x00000001060ffdf5 PyEval_EvalFrameEx + 15416
16  org.python.python               0x00000001060fc093 PyEval_EvalCodeEx + 1641
17  org.python.python               0x00000001060fba24 PyEval_EvalCode + 54
18  org.python.python               0x000000010611ac2c 0x10607c000 + 650284
19  org.python.python               0x000000010611acd3 PyRun_FileExFlags + 137
20  org.python.python               0x000000010611a821 PyRun_SimpleFileExFlags + 718
21  org.python.python               0x000000010612b363 Py_Main + 2995
22  libdyld.dylib                   0x00007fff8e4215fd start + 1

我已經閱讀了https://docs.python.org/2/library/ctypes.html中的python文檔,但沒有發現任何幫助。 我該如何解決?

為了能夠安全地調用函數,您必須正確定義函數原型:

# define your structure
class aStruct(ctypes.Structure):
    _fields_ = [('num', ctypes.c_int),
                ('c', ctypes.c_char]

# this defines aStructPtr to be a pointer
# to an aStruct
aStructPtr = ctypes.POINTER(aStruct)

# next, define the interface to your functions:
lib.newStructPointer.restype = aStructPtr
lib.newStructPointer.argtypes = [] # void, no arguments

# your getter functions both take the structure pointer as inputs
# and return an integer or char
lib.getNumField.restype = ctypes.c_int
lib.getNumField.argtypes = [aStructPtr]

lib.getCharField.restype = ctypes.c_char
lib.getCharField.argtypes = [aStructPtr]

請注意,只要在ctypes中正確聲明了結構,就不需要c getter函數。 以下內容也應該起作用:

s = lib.newStructPointer()
num_value = s.contents.num
char_value = s.contents.c

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM