"Hendrik van Rooyen" <m...@microcorp.co.za> wrote in message news:000f01c96822$5c300f00$0d00a...@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


--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to