Python使用ctypes传递一个char *数组并填充结果 [英] Python using ctypes to pass a char * array and populate results

查看:235
本文介绍了Python使用ctypes传递一个char *数组并填充结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用ctypes在python中创建一个char *数组,以传递给一个库来填充字符串。我期望4个字符串每个长度不超过7个字符。



我的py代码看起来像这样



< p



  primesmile / lib.so)

getAllNodeNames = primesmile.getAllNodeNames
getAllNodeNames.argtypes = [POINTER(c_char_p)]
results =(c_char_p * 4)(addressof(create_string_buffer 7)))
err = getAllNodeNames(results)

lib.cpp

  void getAllNodeNames(char ** array){
DSL_idArray nodes; // this object returns const char * when iterated over
network.GetAllNodeIds(nodes);
for(int i = 0; i <(nodes.NumItems()); i ++){
strcpy(array [i],nodes [i]);
}
}



当我试图运行这个码。我创建了一个测试从C,完美的工作,但在Python我必须设置不正确的指针数组或东西。它似乎到达循环中的第二个节点,然后有一个问题,我从看到从吐出数据到命令行。

解决方案

以下代码适用:



test.py:

  import ctypes 
lib = ctypes.CDLL(./ libtest.so)
string_buffers = [ctypes.create_string_buffer(8)for i in range(4)]
pointers =(ctypes.c_char_p * 4)(* map(ctypes.addressof,string_buffers))
lib .test(pointers)
results = [s.value for s in string_buffers]
打印结果

test.c(使用 gcc test.c -o libtest.so -shared -fPIC )编译为libtest.so:

  #include< string.h> 
void test(char ** strings){
strcpy(strings [0],this);
strcpy(strings [1],is);
strcpy(strings [2],a);
strcpy(strings [3],test!);
}

Aya说,你应该确保有终止零的空间。但我认为你的主要问题是字符串缓冲区是垃圾收集或类似的,因为没有直接引用它了。或者,当没有为它们存储引用时,在字符串缓冲器的创建过程中引起麻烦。例如,这将导致四次相同的地址,而不是不同的地址:

  import ctypes 
pointers = [ctypes。范围(4)中的i的addressof(ctypes.create_string_buffer(8))]
打印指针


I'm trying to use ctypes to create a char * array in python to be passed to a library for populating with strings. I'm expecting 4 strings back no more than 7 characters in length each.

My py code looks like this

testlib.py

from ctypes import *
primesmile = CDLL("/primesmile/lib.so")

getAllNodeNames = primesmile.getAllNodeNames
getAllNodeNames.argtypes = [POINTER(c_char_p)]
results = (c_char_p * 4)(addressof(create_string_buffer(7)))
err = getAllNodeNames(results)

lib.cpp

void getAllNodeNames(char **array){
    DSL_idArray nodes; //this object returns const char * when iterated over
    network.GetAllNodeIds(nodes);
    for(int i = 0; i < (nodes.NumItems()); i++){
    strcpy(array[i],nodes[i]);
    }
}

I keep getting segmentation faults when I try to run this code. I've created a test from C that works perfectly but in Python I must be setting up the pointer array incorrectly or something. It seems to get to the second node in the loop and then have a problem as I've seen from spitting out data into the command line. Any insight would be much appreciated.

解决方案

The following code works:

test.py:

import ctypes
lib = ctypes.CDLL("./libtest.so")
string_buffers = [ctypes.create_string_buffer(8) for i in range(4)]
pointers = (ctypes.c_char_p*4)(*map(ctypes.addressof, string_buffers))
lib.test(pointers)
results = [s.value for s in string_buffers]
print results

test.c (compiled to libtest.so with gcc test.c -o libtest.so -shared -fPIC):

#include <string.h>
void test(char **strings) {
    strcpy(strings[0],"this");
    strcpy(strings[1],"is");
    strcpy(strings[2],"a");
    strcpy(strings[3],"test!");
}

As Aya said, you should make sure there is room for the terminating zero. But I think your main problem was that the string buffer was garbage collected or something similar, as there was no direct reference to it anymore. Or something else is causing trouble in the creation process of the string buffers when no references are stored for them. For example this results in four times the same address instead of different addresses:

import ctypes
pointers = [ctypes.addressof(ctypes.create_string_buffer(8)) for i in range(4)]
print pointers

这篇关于Python使用ctypes传递一个char *数组并填充结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆