python调用c/c++时string的传入与返回深入分析

python调用c/c++时string的传入与返回深入分析

使用ctypes可以轻松实现在python调用c/c++的库,但是这貌似没有对string类型的传入和返回有很好的支持。当把string类型str直接传进c/c++的函数时,发现strlen(str)永远是1。后来我强行输出传入的char* s后面的几位s[0]、s[1]、s[2]、s[3]……时,发现输出是a b c d e f g,每个char输出后都会有个空格,然后我再输出(int)s[0]…..发现那些空格都是’\0’。因此strlen(str)是1原因很明显是因为其读到了’\0’就停下来了。而python的string的一个字符明显是占了2byte的,当字符为英文字母时,后1byte为0,前1byte储存ascII码,这估计是为了支持中文这些复杂的文字,而char*是按照1byte为单位进行读取和写入的,所以就有了上面的现象。所以c/c++处理输入的python的string类型变量时,需要额外传入一个len(str)来获取string的长度,然后再以2byte为单位进行处理。
传入的问题解决了,而返回的问题更麻烦!
c的函数调用完后会自动delete掉函数内开辟的内存,所以返回一个char*指针是没有意义的。那么代替返回值的一个方法是直接改变python的string而不需要返回。这样的话,使用直接传进来的string变量是不行的,因为那是一个复制的变量而不是变量本身。正确的方法是传入那个string变量的指针(地址)。ctypes提供了一个c_wchar_p类型的指针可以用来获取string指针(地址):p=c_wchar_p(str).然后把p当参数传进去就可以了。完整代码如下:
c++代码:

#include <iostream>
#include<cstring>
using namespace std;
//字符串翻转函数,仅限英文
extern "C" _declspec(dllexport) void reverse(char* s,int len) 
{ 
    for(int i=0;i<len*2;i++)
        cout<<s[i];
    cout<<endl;
    char* sc=new char[len];
    for(int i=0;i<len;i++)
    {
    sc[i]=s[i*2];//下标乘2跳过'\0'
    }
    for(int i=0;i<len;i++)
        s[i*2]=sc[len-1-i];
}

python3.5.2代码:

#coding=utf-8 
import ctypes 
from ctypes import *   
ll = ctypes.cdll.LoadLibrary   
lib = ll("D:/py/CDll/Debug/CDll.dll")  
str='abcdefg'
p=c_wchar_p(str)
rst=lib.reverse(p,len(str))

print(p.value)

输出结果如下:
这里写图片描述

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值