在64位下,把一些库封装成C函数,然后编译成so文件供python调用,结果发生了崩溃。
今天试验后发现:如果C函数返回void*等类型,把返回值赋值到python变量后被截断,只剩下低32位的值。
因此,如果C函数中的指针在0xffffffff以上的地址的时候,返回到python中就会被截断。如果再继续使用这个被截断后的地址值,就会发生崩溃。
下面是模拟崩溃的代码:
//C
void* create_object()
{
return new int(0);
}
void free_object(void* obj)
{
delete (int*)obj;
}
#python中这样调用
so = cdll.LoadLibrary('xxxx.so')
obj = so.create_object() #这里被截断
so.free_object(obj) #这里发生崩溃
=====================================================
解决办法也比较简单,不要通过返回值传递指针,而通过指针参数返回:
void create_object(uint64_t* out)
{
*out = (uint64_t)new int(0);
}
void free_object(void* obj)
{
delete (int*)obj;
}
#python中这样调用
so = cdll.LoadLibrary('xxxx.so')
obj = ctypes.c_ulonglong(0)
so.create_object(ctypes.byref(obj))
obj = ctypes.c_void_p(obj.value)
so.free_object(obj)
这里要注意:发现python中的对象的地址都在0xffffffff之内,所以使用byref没发现问题。
byref是否会截断指针,这个还没试验出来。
2013年4月11日星期四
2012年11月28日星期三
python: 转换被错误定义为unicode类型的utf-8编码
某同事的代码中发现,本来是utf-8编码的字符串,从数据库读出来后,被错误返回为u'utf-8内码'这样的格式。
下面是一个简单的转换方法,还原其为正常的utf-8编码:
下面是一个简单的转换方法,还原其为正常的utf-8编码:
>>> a = '测试'
>>> a
'\xb2\xe2\xca\xd4'
>>> b = a.decode('gbk').encode('utf-8')
>>> b
'\xe6\xb5\x8b\xe8\xaf\x95'
>>> c = u'\xe6\xb5\x8b\xe8\xaf\x95'
>>> c
u'\xe6\xb5\x8b\xe8\xaf\x95'
>>> arr = array.array('B')
>>> arr.fromlist([ord(i) for i in c])
>>> print arr.tostring().decode('utf-8').encode('gbk')
测试
>>> a
'\xb2\xe2\xca\xd4'
>>> b = a.decode('gbk').encode('utf-8')
>>> b
'\xe6\xb5\x8b\xe8\xaf\x95'
>>> c = u'\xe6\xb5\x8b\xe8\xaf\x95'
>>> c
u'\xe6\xb5\x8b\xe8\xaf\x95'
>>> arr = array.array('B')
>>> arr.fromlist([ord(i) for i in c])
>>> print arr.tostring().decode('utf-8').encode('gbk')
测试
最终的代码是这样:
import string
import array
s = u'
\xe6\xb5\x8b\xe8\xaf\x95 '
arr = array.array('B')
arr.fromlist([ord(i) for i in s])
print arr.tostring().decode('utf-8').encode('gbk')
如果读者知道更好的转换方法,希望不吝赐教。
2012年11月27日星期二
安装python图标库pycha搞得很郁闷
根据帖子推荐,发现pycha是所有python图标库中比较简单的,于是打算采用这个。
结果,安装这个库花了我两个半天,仍未能解决,打算放弃。
1. 首先在pycha的首页https://bitbucket.org/lgs/pycha/wiki/Home找下载地址。
找了半天居然没有,只有个项目管理软件hg的地址。
好吧,先安装windows下的hg客户端。
2. 安装hg客户端:
http://cdn.bitbucket.org/tortoisehg/files/downloads/tortoisehg-2.6.0-hg-2.4-x86.msi
3. 使用hg下载源码:
hg clone http://bitbucket.org/lgs/pycha
4. 安装上了没效果,原来还需要库 cairo。于是下载cairo
http://www.cairographics.org/releases/py2cairo-1.10.0.tar.bz2
5. cairo库不同于一般python库的安装,居然还需要python的头文件,于是再下载python源码包来编译:
http://www.python.org/ftp/python/2.7/Python-2.7.tgz
6. 再编译cairo,指定头文件的路径,仍然编译不通过……
选择一个不成熟的库,果然很折腾啊!
结果,安装这个库花了我两个半天,仍未能解决,打算放弃。
1. 首先在pycha的首页https://bitbucket.org/lgs/pycha/wiki/Home找下载地址。
找了半天居然没有,只有个项目管理软件hg的地址。
好吧,先安装windows下的hg客户端。
2. 安装hg客户端:
http://cdn.bitbucket.org/tortoisehg/files/downloads/tortoisehg-2.6.0-hg-2.4-x86.msi
3. 使用hg下载源码:
hg clone http://bitbucket.org/lgs/pycha
4. 安装上了没效果,原来还需要库 cairo。于是下载cairo
http://www.cairographics.org/releases/py2cairo-1.10.0.tar.bz2
5. cairo库不同于一般python库的安装,居然还需要python的头文件,于是再下载python源码包来编译:
http://www.python.org/ftp/python/2.7/Python-2.7.tgz
6. 再编译cairo,指定头文件的路径,仍然编译不通过……
选择一个不成熟的库,果然很折腾啊!
2012年9月14日星期五
python PIL: 图片的倒影效果的简单实现
具体的算法就是把图片的每一行对称翻转,然后将透明度从低到高逐行设置。
见代码:
import sys,os
from PIL import Image
if __name__=='__main__':
argc = len(sys.argv)
if argc<3:
print 'usage:%s <file> <dest>'%sys.argv[0]
sys.exit(-1)
im = Image.open(sys.argv[1]).convert('RGBA')
arr = []
(w,h) = im.size
x = 0
y = 0
index = 0
arr_row = []
for pixel in im.getdata():
pixel = list(pixel)
x = index % w
y = index / w
index += 1
pixel[3] = int(256.0*0.2*(float(y)/float(h)))
arr_row.append(tuple(pixel))
if index%w==0 and index>0:
arr = arr_row + arr
arr_row = []
#
im1 = Image.new('RGBA', (w,h))
im1.putdata(arr)
im1.save(sys.argv[2])

见代码:
import sys,os
from PIL import Image
if __name__=='__main__':
argc = len(sys.argv)
if argc<3:
print 'usage:%s <file> <dest>'%sys.argv[0]
sys.exit(-1)
im = Image.open(sys.argv[1]).convert('RGBA')
arr = []
(w,h) = im.size
x = 0
y = 0
index = 0
arr_row = []
for pixel in im.getdata():
pixel = list(pixel)
x = index % w
y = index / w
index += 1
pixel[3] = int(256.0*0.2*(float(y)/float(h)))
arr_row.append(tuple(pixel))
if index%w==0 and index>0:
arr = arr_row + arr
arr_row = []
#
im1 = Image.new('RGBA', (w,h))
im1.putdata(arr)
im1.save(sys.argv[2])
原图和效果见下面:

2012年8月30日星期四
小记:python中用PIL进行图形合成
网站上需要展示一个类似如下的图:
整个图包含了三部分:背景,带透明度设置的阴影,以及封面。三个图通过程序合成成以上的样子。
用PIL实现极为简单,但摸索了差不多半小时才搞好,贴出来,或许对某人有用:
bg = Image.open(r'F:\temp\bg.png').convert('RGBA')
shadow = Image.open(r'F:\temp\shadow.png').convert('RGBA')
cover = Image.open(r'F:\temp\cover.png').convert('RGBA')
#下面这步是关键,蒙版的对象,采用自身即可根据透明度进行运算
bg.paste(shadow, ((bg.size[0]-shadow.size[0])/2,(bg.size[1]-shadow.size[1])/2), shadow)
bg.paste(book, ((bg.size[0]-book.size[0])/2,(bg.size[1]-book.size[1])/2))
bg.save(r'F:\temp\result.png', format='png')
整个图包含了三部分:背景,带透明度设置的阴影,以及封面。三个图通过程序合成成以上的样子。
用PIL实现极为简单,但摸索了差不多半小时才搞好,贴出来,或许对某人有用:
bg = Image.open(r'F:\temp\bg.png').convert('RGBA')
shadow = Image.open(r'F:\temp\shadow.png').convert('RGBA')
cover = Image.open(r'F:\temp\cover.png').convert('RGBA')
#下面这步是关键,蒙版的对象,采用自身即可根据透明度进行运算
bg.paste(shadow, ((bg.size[0]-shadow.size[0])/2,(bg.size[1]-shadow.size[1])/2), shadow)
bg.paste(book, ((bg.size[0]-book.size[0])/2,(bg.size[1]-book.size[1])/2))
bg.save(r'F:\temp\result.png', format='png')
订阅:
博文 (Atom)
