c/c++语言开发共享Python使用ctypes传递char *数组并填充结果

我正在尝试使用ctypes在python中创建一个char *数组,以传递给库以填充字符串。 我期待4个字符串的长度不超过7个字符。

我的py代码看起来像这样

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]); } } 

当我尝试运行此代码时,我不断收到分段错误。 我已经从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] print results 

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

     #include  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.addressof(ctypes.create_string_buffer(8)) for i in range(4)] print pointers 

    在这一行:

     results = (c_char_p * 4)(addressof(create_string_buffer(7))) 

    您正在创建一个7字节的缓冲区,然后尝试使用它来保存4个字符指针(每个可能是4个字节),然后还将4个8字节字符串复制到它可能碰巧指向的随机地址中。 您需要为每个字符串分配一个缓冲区,并分配指针数组。 像这样的东西:

     s = [] for i in range(4): s[i] = create_string_buffer(8) results = (c_char_p * 4)(s); 

    我不能(轻松)测试代码,但根据你所说的,我的猜测就是问题在于……

     results = (c_char_p * 4)(addressof(create_string_buffer(7))) 

    根据create_string_buffer()的Python文档…

    init_or_size必须是一个整数,它指定数组的大小,或者是一个用于初始化数组项的字符串。

    如果将字符串指定为第一个参数,则将缓冲区设置为大于字符串长度的一个项目,以便数组中的最后一个元素是NUL终止字符。 可以将整数作为第二个参数传递,如果不应使用字符串的长度,则允许指定数组的大小。

    …这意味着它正在创建一个char[7] ,但strcpy()将尝试复制字符串的NULL终止符,因此如果你的最大“节点名称”长度为7个字符,则需要一个char[8]保持NULL ,尽管你可能会使用memcpy(array[i], nodes[i], 7)而不是strcpy()

    无论哪种方式,使用create_string_buffer(8)代替它可能是最安全的。

    需要了解更多c/c++开发分享Python使用ctypes传递char *数组并填充结果,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享Python使用ctypes传递char *数组并填充结果相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/979240.html

      (1)
      上一篇 2021年12月12日
      下一篇 2021年12月12日

      精彩推荐