ImageMagick与Python ctypes的段错误
我在用 Python 的 ctypes
库调用 ImageMagick 这个库。写了一段简单的代码,但在 Mac 上运行时出现了崩溃,提示是段错误(KERN_INVALID_ADDRESS
)。
from ctypes import *
from ctypes.util import find_library
lib = CDLL(find_library('MagickWand'))
lib.MagickWandGenesis()
wand = lib.NewMagickWand()
lib.MagickReadImage(wand, 'mona-lisa.jpg')
lib.DestroyMagickWand(wand)
lib.MagickWandTerminus()
这段代码在 Linux 和 Windows 上都能正常工作,但在 Mac OS X Lion 上却总是崩溃。我尝试了多种方式来安装 ImageMagick(官方的二进制包、Homebrew、传统的 ./configure && make
),但每次都崩溃。
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000000009a7638
0x000000010149a8d1 in MagickReadImage ()
不仅是 MagickReadImage()
这个函数会崩溃,IsMagickWand()
这个函数也会崩溃。我猜测可能是 NewMagickWand()
返回了一个错误的指针,或者是 Mac 上的 ctypes
处理指针的方式不对,但我不太确定。
在这种情况下,问题出在哪里呢?
2 个回答
1
我把下面的代码改成了:
lib.MagickReadImage(wand, 'mona-lisa.jpg')
变成了:
f2 = lib.MagickReadImage
f2.argtypes = [c_void_p, c_char_p]
f2(wand, 'mona-lisa.jpg')
所以,现在运行得很好。
0
很可能这是个32位和64位的问题。你测试过的Mac版本是唯一一个64位的程序吗?或者说,你在Windows和Linux版本中运气不错,恰好它们返回的指针格式是0x00000000xxxxxxxx。
wand = lib.NewMagickWand()
NewMagickWand这个函数返回了一个指针,但你没有告诉ctypes要期待一个指针。现在ctypes默认把返回值当成32位整数。你需要在调用NewMagickWand之前加上这一行。
lib.NewMagickWand.restype = c_void_p
这行代码告诉ctypes,NewMagickWand返回的是一个指针。