ImageMagick与Python ctypes的段错误

0 投票
2 回答
1033 浏览
提问于 2025-04-17 05:05

我在用 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返回的是一个指针。

撰写回答