On Sun, Jul 18, 2010 at 2:38 PM, Dino Viehland <di...@microsoft.com> wrote: > TP wrote: >> I'm using IronPython 2.6.1 for Net 2.0 and VS2008 on Windows XP SP3. >> >> I have a python script that lets me access the Leptonica Image >> Processing C library (http://leptonica.com/) using the ctypes module. >> >> Everything seems to work fine with cpython 2.6. I can correctly load >> leptonlib.dll, create leptonica PIX images, manipulate them, and even >> display them using PyQT. I can use VS2008 to put breakpoints on >> leptonica C functions and step through the C code in the VS2008 >> debugger. >> >> I thought I'd give IronPython a try since it also has ctypes, but I >> ran into a number of problems. >> >> The leptonlib.dll must be loading since I am able to correctly get >> back the library's version string. That is the following works: >> >> _getLeptonlibVersion = _leptonlib.getLeptonlibVersion >> _getLeptonlibVersion.restype = ctypes.c_void_p >> addr = _getLeptonlibVersion() >> version = ctypes.string_at(addr) >> >> However the following code doesn't seem to work under IronPython 2.6.1: >> >> pix = Pix(dimensions=(10,20,1)) >> >> where essentially the following is called: >> >> _pix = ctypes.c_void_p() >> _pix.value = _leptonlib.pixCreate(width, height, depth) >> self._pix = _pix >> >> and I want to treat _pix as an opaque ptr I just hand back to >> leptonica whenever it needs it. For example: >> >> def height(self): >> """Get height of pix in pixels.""" >> return _leptonlib.pixGetHeight(self._pix) >> >> Which works with cpython but returns something other than 20 with >> IronPython. >> >> By specifying "-X:Debug -X:FullFrames -X:Tracing leptonica.py" as the >> arguments to C:\Program Files\IronPython 2.6\ipy.exe I can get >> IronPython to correctly stop at places in my script where I put: >> >> import pdb >> pdb.set_trace() >> >> when I debug leptonlibd.dll with VS2008. However, my breakpoints on >> leptonica's C functions never seem to get hit. This works fine if I >> instead use python26.exe as command to launch when debugging. > > You should only need -X:Debug to get debugging under VS. pdb uses a > more Pythonic form of debugging but there's no support for it in VS.
Let me be clear here. I am using the VS2008 Solution that I use to create leptonlib.dll. I am debugging that dll by right-clicking its project and setting its Configuration Properties | Debugging tab to: Command: C:\Program Files\IronPython 2.6\ipy.exe Arguments: -X:Debug -X:FullFrames -X:Tracing -i leptonica.py Working Directory: C:\leptonica\ If I only use -X:Debug as you suggest I get the following error: Traceback (most recent call last): File "leptonica.py", line 458, in <module> File "leptonica.py", line 176, in __init__ File "C:\Program Files\IronPython 2.6\Lib\pdb.py", line 1220, in set_trace AttributeError: 'module' object has no attribute '_getframe'>>> Googling, I determined that I needed to add at least -X:FullFrames, and by trial and error I found I also needed -X:Tracing. (I wasn't able to find any documentation on ipy.exe's command line switches? I just ran "ipy.exe -h" to dump out the short help description and took a wild guess at which might be useful) >> >> Ideally I like to have the VS Debugger stop in leptonlibd.dll's >> pixCreate() C function just before it returns its value so I can >> compare that to what I get back on the IronPython side. >> >> So how's does one use VS2008 to step through C functions in DLLs that >> are loaded by IronPython and the ctypes module? > > Do you have symbols (.PDB files) for leptonlibd.dll? You'll need symbols > to be able to step through the C code. You can still probably set a > breakpoint > in the function because it's DLL exported - I think you can debug->new > breakpoint and enter leptonlibd!pixCreate. Even w/o symbols you could > step through the assembly. leptonlibd.dll is created with the C7 Compatible (/Z7) compiler switch. This embeds the debugging info directly in the DLL so no .pdb file is produced. It also does NOT use pre-compiled headers. I might also point out that the same exact .dll will hit breakpoints if debugged with python26.exe rather than ipy.exe. Perhaps since ipy.exe is built on top of .NET the VS2008 debugger handles any .dll's loaded by it differently? I know for example that the VS2008 debugger didn't like trying to run the IronPython for NET 4.0 version of ipy.exe (I gather you have to use VS2010 if you want to do that). Trying to set a breaking at leptonlibd!pixCreate didn't work. >> >> Secondly, am I using ctypes wrong, and does my code only work by >> happenstance for cpython. > > I don't see anything particularly wrong on your side and this looks like > a pretty simple call. I would assume the C functions are defined as: > > void* pixCreate(int width, int height, int depth); > int pixGetHeight(void* pixel); That's correct. > > I would hope we're getting all of this right as it seems like simple stuff > that should be tested somewhere. My first guess would be maybe we're > getting the calling convention wrong. Maybe it needs to be a WinDLL instead > of a CDLL? Maybe there's a check in the Python code for sys.platform which > is looking for win32 and uses WinDLL to open the DLL instead of CDLL on > Windows? More information on the problem: I decided to explicitly set the restype even though it's the default return type. I get the same exact behavior as my original code. Works with cpython, doesn't work with IronPython 2.6.1. If I have with the following python code: _pix = ctypes.c_void_p() _pixCreate = _leptonlib.pixCreate _pixCreate.restype = ctypes.c_int import pdb pdb.set_trace() _pix.value = _pixCreate(width, height, depth) I can do the following in the Command Window after pdb breaks into the script: > leptonica.py(180)__init__() -> _pix.value = _pixCreate(width, height, depth) (Pdb) n > leptonica.py(181)__init__() -> self._pix = _pix (Pdb) _pix.value *** AttributeError: 'cell' object has no attribute 'value' This is a bit strange since I just assigned to _pix.value. Investigating further: (Pdb) _pix <cell at 43: c_void_p object at 44> So instead of assigning to _pix.value (that is changing an attribute of _pix), IronPython is clobbering _pix? If I instead separately assign the result of pixCreate() to a temporary variable: width, height, depth = dimensions _pix = ctypes.c_void_p() _pixCreate = _leptonlib.pixCreate _pixCreate.restype = ctypes.c_int import pdb pdb.set_trace() addr = _pixCreate(width, height, depth) _pix.value = addr Once pdb stops the script: > leptonica.py(178)__init__() -> addr = _pixCreate(width, height, depth) (Pdb) n > leptonica.py(179)__init__() -> _pix.value = addr (Pdb) addr <cell at 43: int object at 44> (Pdb) type(addr) <type 'cell'> (Pdb) dir(addr) ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents'] (Pdb) type(addr.cell_contents) <type 'int'> (Pdb) addr.cell_contents 77491296 So instead of returning an int, ctypes under IronPython is returning a "cell" in this case for some reason? Compare this to what I get with cpython. If I change the leptonlib.dll project Configuration Properties | Debugging tab to: Command: c:\Python26\python26.exe Arguments: -i leptonica.py Working Directory: C:\leptonica\ Debugging by typing F5 (or choosing Debug > Start Debugging) without changing leptonica.py or leptonlibd.dll in any way, I then hit all my breakpoints set in leptonlibd.dll. I get warning messages about python.exe having stopped for each breakpoint and I just click the Continue button to close them. After I type F5 to get past all my C function breakpoints, pdb stops my script with: > leptonica.py(178)__init__() -> addr = _pixCreate(width, height, depth) (Pdb) n > leptonica.py(179)__init__() -> _pix.value = addr (Pdb) addr 19492760 (Pdb) hex(addr) '0x1296f98' and 0x1296f98 matches what I see for the return value of pixCreate() from the VS2008 debugger. I also tried debugging my leptonica.py script by following the directions in the IronPython tutorial. I made a new Solution with the following Debugging properties: Command: C:\Program Files\IronPython 2.6\ipy.exe Arguments: -X:Debug -i leptonica.py Working Directory: C:\leptonica\ I added my leptonlib.vcprog file to this solution by right-clicking it and choosing Add > Existing Project. I again set a breakpoint at the C function pixCreate(). I also set various breakpoints in my leptonica.py script. Pressing F5 to Start Debugging, I now hit my leptonica.py breakpoints but still don't hit any C function breakpoints. >From the locals window I can see that addr is: addr 0x00bf6ea0 object {int} Looking in a Memory window at "addr" I see: 0x06AAB590 79332d70 00bf6ea0 00000000 793042f4 00000001 33b4c9bc p-3y n¿.....ôB0y.....É´3 So there's something else at "addr", but the next int is 0x00bf6ea0 again. The memory at 0x00bf6ea0 looks correct: 0x00BF6EA0 0a 00 00 00 14 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 ...................... 0x00BF6EB6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f8 6e bf 00 ..................øn¿. 0x00BF6ECC fd fd fd fd 10 00 0b 00 f2 01 0c 00 80 6e bf 00 00 00 00 00 00 00 ýýýý....ò...€n¿....... 0x00BF6EE2 00 00 00 00 00 00 50 00 00 00 01 00 00 00 4d 00 00 00 fd fd fd fd ......P.......M...ýýýý At least it looks to me like those are indeed ints for width, height & depth which is what a PIX starts out with. After: _pix.value = addr I see this in the locals window: _pix "ctypes.c_void_p instance" object {IronPython.NewTypes.IronPython.Modules.SimpleCData_4$4} In the Immediate window I get: _pix "ctypes.c_void_p instance" base {IronPython.Modules.CTypes.SimpleCData}: "ctypes.c_void_p instance" .class: PythonType: "c_void_p" .dict: null .slots_and_weakref: null But I am unable to figure out how to tell what the "value" of _pix is? _______________________________________________ Users mailing list Users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com