ctypes & strings
Mark Tolonen
metolone+gmane at gmail.com
Sat Dec 27 14:16:35 EST 2008
"Hendrik van Rooyen" <mail at microcorp.co.za> wrote in message
news:000f01c96822$5c300f00$0d00a8c0 at hendrik...
>
> Red Rackham wrote:
>
>>I would like to pass a string into a dll function. I notice that to pass
>>using
> ctypes, it has to be a ctypes type. >Looking at the ctypes doc page I
> don't see
> a c_string class.
>
> The following seems to work for me:
>
> In the c programme:
>
> /*
> This routine outputs and inputs a symmetric block of bytes, writing
> the outputs out and reading the inputs in, replacing the chars in the
> original output string
> */
>
> unsigned char read_write (unsigned char *inputs, unsigned char *outputs,
> int
> lenin, int lenout)
> {
> int i = 0;
> int addr = 0;
> int addrhi = 0;
> int oind = 0;
> char rv;
> while (i < lenin)
> {
> addrhi = i >> 8 & 0x3f; // we can have 64 * 256 adresses in the
> top
> 6 + 8 bits
> addr = i & 0xff; // this is low order
> rv = put_1(addrhi|0xd0); // put out the addy
> rv = put_3(addr);
> rv = put_1(addrhi|0x90); // make a read strobe on bit 6
> inputs[i] = get_0() ^ 255; // read the char
> rv = put_1(addr|0xd0); // raise strobe again
> i++;
> }
>
> while (i < lenin + lenout)
> {
> oind = i - lenin; // index into outputs start at 0
> addrhi = i >> 8 & 0x3f; // we can have 64 * 256 adresses in the
> top
> 6 + 8 bits
> addr = i & 0xff; // this is low order
> rv = put_1(addrhi|0xd0); // put out the addy
> rv = put_3(addr);
> rv = put_0(outputs[oind]); // put out the output
> rv = put_1(addrhi|0x50); // make a write strobe on bit 7
> rv = put_1(addrhi|0xd0); // raise write strobe again
> i++;
> }
> return *inputs;
> }
>
>
> Then in the python it is used as follows:
>
> import sys, os, ctypes, time
>
> io = ctypes.cdll.LoadLibrary('./lib_gpio.a')
>
> def do_io(ins, outs): # ins and outs are normal python strings that must
> exist
>
> # this routine happens to work by side effect - the ins string is
> changed by the c routine
>
> r = io.read_write(ins,outs,len(ins),len(outs))
> return
>
> The c routine will actually break Python's normal string
> immmutability and give you back a changed ins.
>
> It is in general not a good idea to change the passed string
> like I am doing - but you wanted to know how
> to pass a python string, and the outs example should get
> you going - a string is an array of characters in c...
Here's an example using mutable buffers:
------------ x.c --> x.dll -----------------------
#include <string.h>
__declspec(dllexport)
int fill(char *buf,int len)
{
strncpy(buf,"initialized string",len-1);
buf[len-1]=0;
return strlen(buf);
}
--------------------------------------------------
PythonWin 2.6.1 (r261:67517, Dec 4 2008, 16:51:00) [MSC v.1500 32 bit
(Intel)] on win32.
Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' for
further copyright information.
>>> from ctypes import *
>>> x=CDLL('x.dll')
>>> s=create_string_buffer('string',10)
>>> s.raw
'string\x00\x00\x00\x00'
>>> s.value
'string'
>>> x.fill(s,len(s))
9
>>> s.raw
'initializ\x00'
>>> s.value
'initializ'
>>> s=create_string_buffer('string',20)
>>> x.fill(s,len(s))
18
>>> s.raw
'initialized string\x00\x00'
>>> s.value
'initialized string'
--Mark
More information about the Python-list
mailing list