ctypes question


N

News Wombat

Hi everyone,

I've been experimenting with the ctypes module and think it's great.
I'm hitting a few snags though with seg faults. I attached two links
that holds the code. The line i'm having problems with is this,

sn=clibsmi.smiGetNextNode(pointer(sno),SMI_NODEKIND_ANY)

It will work one time, and if I call it again with the result of the
previous, even though the result (a c struct) looks ok, it will
segfault. I think it's a problem with pointers or maybe the function
in the c library trying to change a string that python won't let it
change. I'm stuck, any tips would be appreciated. Thanks, and Merry
Christmas!

constants.py: http://pastebin.com/HvngjzZN
libsmi.py: http://pastebin.com/19C9kYEa
 
Ad

Advertisements

M

Mark Tolonen

News Wombat said:
Hi everyone,

I've been experimenting with the ctypes module and think it's great.
I'm hitting a few snags though with seg faults. I attached two links
that holds the code. The line i'm having problems with is this,

sn=clibsmi.smiGetNextNode(pointer(sno),SMI_NODEKIND_ANY)

It will work one time, and if I call it again with the result of the
previous, even though the result (a c struct) looks ok, it will
segfault. I think it's a problem with pointers or maybe the function
in the c library trying to change a string that python won't let it
change. I'm stuck, any tips would be appreciated. Thanks, and Merry
Christmas!

constants.py: http://pastebin.com/HvngjzZN
libsmi.py: http://pastebin.com/19C9kYEa

Well, I can't run your code, but I think you should pass the original "sn"
pointer from smiGetNode() and not a pointer(sno). The values are not the
same and the library probably relies on passing the original pointer back
into smiGetNextNode. sn.contents returns a new SmiNode object so its
pointer will be different.

-Mark
 
M

MrJean1

It is not entirely clear what the functions and especially what their
signatures are in that C library clibsmi.

In general, for shared libraries, you need to define those first as
prototype using ctypes.CFUNCTYPE() and then instantiate each prototype
once supplying the necessary parameter flags using
prototype(func_spec, tuple_of_param_flags). See sections 15.16.2.3
and 4 of the ctypes docs*.

Take a look the Python bindings** for the VLC library, the file called
vlc.py***. The function _Cfunction is used to create the Python
callable for each C function in that VLC library. All the Python
callables are in the second half of the vlc.py file, starting at line
2600.

Hope this helps,

/Jean

*) <http://docs.python.org/library/ctypes.html#foreign-functions>

**) <http://wiki.videolan.org/Python_bindings>

***) <http://git.videolan.org/?p=vlc/bindings/
python.git;a=tree;f=generated;b=HEAD>
 
N

News Wombat

In general, for shared libraries, you need to define those first as
prototype using ctypes.CFUNCTYPE() and then instantiate each prototype
once supplying the necessary parameter flags using
prototype(func_spec, tuple_of_param_flags).  See sections 15.16.2.3
and 4 of the ctypes docs*.

I tried the cfuntype and proto steps, and it's not crashing now
(that's good), but now i'm just left with null pointers as a return
object. I'm still working through all of the examples you sent. They
were extremely helpful. Here's where I'm at now...

What is strange is I can actually get smiGetNode to work if I don't
cfunctype/proto it. If i do, nada. however, the smiGetNextNode fails
no matter what, usually with a segfault, but depending on how i
construct it, sometimes a null pointer.

constants.py: http://pastebin.com/f3b4Wbf0
libsmi.py: http://pastebin.com/XgtpG6gr
smi.c (the actual function): http://pastebin.com/Pu2vabWM
 
M

MrJean1

Try again after changing line 16 to

sn = SmiGetNode(None, "1.3.6.1.2.1.2.2")

Because, SmiGetNode is a Python function which accepts Python objects
as arguments. Passing is a ctypes object oid is incorrect.

/Jean
 
Ad

Advertisements

M

Mark Tolonen

News Wombat said:
I tried the cfuntype and proto steps, and it's not crashing now
(that's good), but now i'm just left with null pointers as a return
object. I'm still working through all of the examples you sent. They
were extremely helpful. Here's where I'm at now...

What is strange is I can actually get smiGetNode to work if I don't
cfunctype/proto it. If i do, nada. however, the smiGetNextNode fails
no matter what, usually with a segfault, but depending on how i
construct it, sometimes a null pointer.

constants.py: http://pastebin.com/f3b4Wbf0
libsmi.py: http://pastebin.com/XgtpG6gr
smi.c (the actual function): http://pastebin.com/Pu2vabWM

constants.py, in SmiNode and SmiModule definitions:
- Any field defined "char*" in C should be "c_char_p" not
"POINTER(c_char_p)" (which is char**).

The function definition can be simplified, and 2nd argument corrected
(c_char_p not POINTER(c_char_p)). Python strings can be passed directly to
c_char_p arguments.

SmiGetNode = clibsmi.smiGetNode
SmiGetNode.argtypes = [POINTER(SmiModule),c_char_p]
SmiGetNode.restype = POINTER(SmiNode)
oid = "1.3.6.1.2.1.2.2"
sn=SmiGetNode(None,oid)

Give these fixes a try...

-Mark
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top