Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Python Programming Language

with ctypes, how to parse a multi-string


Hi,

I am currently dealing with ctypes, interfacing with winscard libbrary
(for smart card access).

Several APIs (e.g. SCardListReaderGroupsW ) take a pointer to an
unicode string as a parameter , which points at function return to a
"sequence" of unicode strings, NULL terminated. The last string is
double NULL terminated. (of course buffer length is also returned as
another parameter).

e.g. it could return something like
'group1\x00group2\x00group3\x00\x00'

What should I use as argtypes to my function prototype in order to
gain access to the full list? using c_wchar_p works, but it resolves
the string until it reaches the first \x00, resulting in having access
to the first entry of the list only.

as reference, my current ctypes mapping for this API is:

# extern WINSCARDAPI LONG WINAPI
# SCardListReaderGroupsW(
#     IN      SCARDCONTEXT hContext,
#     OUT     LPWSTR mszGroups,
#     IN OUT  LPDWORD pcchGroups);

_ListReaderGroups = scardlib.SCardListReaderGroupsW
_ListReaderGroups.argtypes = [ c_ulong, c_void_p, c_void_p ]
_ListReaderGroups.restype  = c_ulong

Calling the API looks like:

pcchreadergrp = c_long(SCARD_AUTOALLOCATE)
groups   = c_wchar_p()

_ListReaderGroups( ctx, byref(groups), byref(pcchreadergrp))

Should I be using some array/ctypes.cast() combination to gain access
to all returned characters?

Eric schrieb:

A c_wchar_p instance represent a (one!) zero-terminated string, as you
already know.  A POINTER(c_wchar) instance is more flexible, you should
use that instead.  It can be indexed/sliced with arbitrary indexes.

Here is a simple script to get you started:

"""
from ctypes import *

# Normally, the function call will fill the buffer:
buf = create_unicode_buffer("first\0second\0third\0")

# The pointer you will pass to the function call
ptr = cast(buf, POINTER(c_wchar))

# function call omitted

# Print the raw result
print ptr[:len(buf)]

# Print a list of strings
print ptr[:len(buf)].split("\0")
"""

Thomas

On May 31, 2:52 pm, Thomas Heller <thel@ctypes.org> wrote:

Thanks Thomas, it works as expected!

Regards,

Eric

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc