Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #109563

Re: Trying to pass sys.argv as (int argc, char **argv) using ctypes

Path csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail
From eryk sun <eryksun@gmail.com>
Newsgroups comp.lang.python
Subject Re: Trying to pass sys.argv as (int argc, char **argv) using ctypes
Date Mon, 6 Jun 2016 13:47:11 +0000
Lines 75
Message-ID <mailman.36.1465220874.2306.python-list@python.org> (permalink)
References <6a5f4f7b-37e1-42dd-b024-be3411659930@googlegroups.com> <CACL+1as_1A-L44iKQ5mE9kfffS9ASRTbHtk4_5T80tNZt_07bQ@mail.gmail.com>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8
X-Trace news.uni-berlin.de tUxcwdZ6qCsEpZQHygK0kQzV6cFqgIqDCZ/wr1khQ5gw==
Return-Path <eryksun@gmail.com>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'args': 0.04; 'modify': 0.04; 'error:': 0.05; 'sys': 0.05; 'converts': 0.07; 'strings.': 0.07; 'arg': 0.09; 'c_int': 0.09; 'mode,': 0.09; 'naturally': 0.09; 'subject:ctypes': 0.09; 'subject:using': 0.09; 'unpack': 0.09; 'python': 0.10; 'do,': 0.15; 'value.': 0.15; '2016': 0.16; 'cased': 0.16; 'count.': 0.16; 'element.': 0.16; 'expects': 0.16; 'handle,': 0.16; 'instantiate': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'simpler,': 0.16; 'storing': 0.16; 'subject:pass': 0.16; 'terminator,': 0.16; "type's": 0.16; 'value:': 0.16; 'wrote:': 0.16; 'string': 0.17; 'byte': 0.18; 'char': 0.18; 'element': 0.18; 'integer': 0.18; 'passes': 0.18; 'pointer': 0.18; "shouldn't": 0.18; 'cc:2**0': 0.20; 'arguments': 0.22; 'ctypes': 0.22; 'pass': 0.22; 'am,': 0.23; 'elements': 0.23; 'passing': 0.23; 'import': 0.24; 'header:In-Reply-To:1': 0.24; 'mon,': 0.24; '(which': 0.26; 'error': 0.27; 'parameters': 0.27; 'message-id:@mail.gmail.com': 0.27; 'function': 0.28; 'ansi': 0.29; 'pointer.': 0.29; 'array': 0.29; 'character': 0.29; 'code:': 0.29; 'convert': 0.29; 'work.': 0.30; 'certainly': 0.30; 'subject:) ': 0.32; 'instances': 0.33; 'limitations': 0.33; 'null': 0.33; 'list': 0.34; 'received:google.com': 0.35; 'skip:c 30': 0.35; 'generic': 0.35; 'instance': 0.35; 'expected': 0.35; "isn't": 0.35; 'should': 0.36; 'instead': 0.36; 'received:209.85': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'signature': 0.37; 'received:209': 0.38; 'received:209.85.214': 0.39; 'skip:e 20': 0.39; 'to:addr:python.org': 0.40; 'mark': 0.40; 'default': 0.61; 'more': 0.63; 'skip:a 40': 0.64; 'due': 0.65; 'special': 0.73; 'directly.': 0.76; 'mistakenly': 0.91
DKIM-Signature v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=NtQjuigfGpiO7Oud5VBI6h/ZXkb8eY3+lgrp3akPm3c=; b=bcEt7bQiTZIWHGh6ott41+03wzHZ8lmyFMiY9W1Hg0kaN4DQOtNu+tqAoiiefTf4Wb FSU8CeLtoxBs1WUsnjy7AeXMKNwAT+ZQoKisOrCxRrFQSICwRSvi3zt4H9sMDwjeel4z PpmsiC4zVCZie6oASokKjFqN6YLwzJ0Fp55c3+Um8rWPVR8YB7n/PVoAZDOrfNILiF3n QzTMAe/uJZZd8wwejOhe7TdwSArb67m2fkosEMi5nQVIXqg3Qsiy1stRCwyf7bpgZpAu vOOTSs2q/8YbpQyFpZrH/wLfBC8U9AA1KC+Dyx3BmYoqorp14q4aD4kXtnwqe8Skuf9Z b1jA==
X-Google-DKIM-Signature v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=NtQjuigfGpiO7Oud5VBI6h/ZXkb8eY3+lgrp3akPm3c=; b=Rz14BOTZC9iV0TBYjrU54mhF5d6gBLUN4ZTifEINSZSAjmj4b8uu4TaUp/FGBmH1aj Cm0bX9PXtIJ97XD8v+7XpVao9MmVO0kmjfbOn4pZV8FGZyhnAaNycD6TXpBw7L8HETbL xsF8ZrT8DPgKZ2PlBmoeQBhhZPE1STQJyIcIxuc5uJGlmreEsH+pUiVQgA+Is0kFKlAx K40strIRjVLswNDacKmcGnArpl/xZdaH+YR3FtFo6G9VPcMv4KXOnwM2+0xmNWinyW9j f/3ZsEYOQGc2FwyCwKyQPiXJCRLg5ldA3Y4nSrSYTuvCy3rXwe1cp7hFwesH4WWO8nD2 Ysmw==
X-Gm-Message-State ALyK8tINKC/hcCBend9dVFzBBlBFskkEtQJtRZw2stQX+0mEXOvmHtzZ0SNDHk5D5R4Cin4BdRG5PL63db+EFw==
X-Received by 10.36.65.97 with SMTP id x94mr15570054ita.16.1465220871420; Mon, 06 Jun 2016 06:47:51 -0700 (PDT)
In-Reply-To <6a5f4f7b-37e1-42dd-b024-be3411659930@googlegroups.com>
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.22
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID <CACL+1as_1A-L44iKQ5mE9kfffS9ASRTbHtk4_5T80tNZt_07bQ@mail.gmail.com>
X-Mailman-Original-References <6a5f4f7b-37e1-42dd-b024-be3411659930@googlegroups.com>
Xref csiph.com comp.lang.python:109563

Show key headers only | View raw


On Mon, Jun 6, 2016 at 9:50 AM, Mark Summerfield <list@qtrac.plus.com> wrote:
>
> Lib = ctypes.cdll.LoadLibrary("libthing")

Use ctypes.CDLL('libthing'). It's simpler, plus it's the only way to
pass the handle, mode, and use_errno parameters if you need them.

> LibOpen.restype = ctypes.c_int

This line isn't required because c_int is the default result type.

> argc = ctypes.c_int(len(sys.argv))

ctypes automatically converts integer arguments that are passed by
value. You only need to create a c_int when you're passing by
reference.

> Args = ctypes.c_char_p * len(sys.argv)

The argv array in ANSI C should have length `argc + 1`. There's a
final null terminator, even though it's redundant given the argc
count.

> args = Args(*[ctypes.c_char_p(arg.encode("utf-8"))
>               for arg in sys.argv])

There's no need to create a list just to unpack it. You can use a for
loop to populate the array directly. Also, you don't have to manually
instantiate c_char_p instances when storing the elements of a c_char_p
array; the base type's getfunc will convert Python byte strings.

Also, since the function signature isn't `const char **`, you should
use ctypes.create_string_buffer just in case the function expects to
be able to modify the argv strings. This requires switching from using
c_char_p to a more generic POINTER(c_char).

> argv = ctypes.pointer(args)
> LibOpen(argc, ctypes.byref(argv))

C array arguments are passed as a pointer to the first element. You
don't have to manually create a pointer. And if you do, certainly you
shouldn't pass it by reference. That mistakenly passes a pointer to
the pointer to the first element of the argv array (which is a pointer
to the first character in the first string argument). Naturally you
get the following error:

> expected LP_c_char_p instance instead of pointer to LP_c_char_p_Array_1

Due to limitations in ctypes you also get the following error when you
pass the pointer by value:

> expected LP_c_char_p instance instead of LP_c_char_p_Array_1

Only passing the array directly is special cased for this to work.

Try the following code:

    import sys
    import ctypes

    lib = ctypes.CDLL('libthing')

    LP_c_char = ctypes.POINTER(ctypes.c_char)
    LP_LP_c_char = ctypes.POINTER(LP_c_char)

    lib.LibOpen.argtypes = (ctypes.c_int, # argc
                            LP_LP_c_char) # argv

    argc = len(sys.argv)
    argv = (LP_c_char * (argc + 1))()
    for i, arg in enumerate(sys.argv):
        enc_arg = arg.encode('utf-8')
        argv[i] = ctypes.create_string_buffer(enc_arg)

    lib.LibOpen(argc, argv)

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Trying to pass sys.argv as (int argc, char **argv) using ctypes Mark Summerfield <list@qtrac.plus.com> - 2016-06-06 02:50 -0700
  Re: Trying to pass sys.argv as (int argc, char **argv) using ctypes eryk sun <eryksun@gmail.com> - 2016-06-06 13:47 +0000
    Re: Trying to pass sys.argv as (int argc, char **argv) using ctypes Mark Summerfield <list@qtrac.plus.com> - 2016-06-06 07:08 -0700

csiph-web