Timothy W. Grove | 19 Mar 17:11 2015

Calling Objective C functions with ctypes

I have been trying to get the following code copied from another forum to work on my system (OSX 10.6, 10.8, Python 3.3 installed via MacPorts), and it just won't. It seems to be finding the 'AppKit' and 'objc' libraries okay, but it is not getting the classes 'NSSpeechSynthesizer' or 'NSAutoreleasePool', so 'count' ends up as '0' and everything falls over from there.

I did notice from the "print voiceNames" statement that this code must be pre-python 3, so are there any obvious changes needed to bring this up to date? Thanks for any help or suggestions.

Best regards,
Tim Grove
[from http://stackoverflow.com/questions/1490039/calling-objective-c-functions-from-python/1490644#1490644]
import ctypes
import ctypes.util

# Need to do this to load the NSSpeechSynthesizer class, which is in AppKit.framework
appkit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('AppKit'))
objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))

objc.objc_getClass.restype = ctypes.c_void_p
objc.sel_registerName.restype = ctypes.c_void_p
objc.objc_msgSend.restype = ctypes.c_void_p
objc.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p]

# Without this, it will still work, but it'll leak memory
NSAutoreleasePool = objc.objc_getClass('NSAutoreleasePool')
pool = objc.objc_msgSend(NSAutoreleasePool, objc.sel_registerName('alloc'))
pool = objc.objc_msgSend(pool, objc.sel_registerName('init'))

NSSpeechSynthesizer = objc.objc_getClass('NSSpeechSynthesizer')
availableVoices = objc.objc_msgSend(NSSpeechSynthesizer, objc.sel_registerName('availableVoices'))

count = objc.objc_msgSend(availableVoices, objc.sel_registerName('count'))
voiceNames = [
  ctypes.string_at(
    objc.objc_msgSend(
      objc.objc_msgSend(availableVoices, objc.sel_registerName('objectAtIndex:'), i),
      objc.sel_registerName('UTF8String')))
  for i in range(count)]
print voiceNames

objc.objc_msgSend(pool, objc.sel_registerName('release'))
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
狂禅 | 11 Mar 03:49 2015

who can tell me the difference in ctypes.sizeof between Ironpython and python in using ctypes to create structure?

recently i meet a problem in using Ironpython.
    import ctypes as ct
   
    class Data(ct.LittleEndianStructure):         
        _pack_      = 2
        _fields_    = [
           
            ('a',ct.c_ubyte),
            ('b',ct.c_ubyte),
            ('c',ct.c_ubyte),
            ('d',ct.c_ushort),
            ('e',ct.c_uint),
            ('f',ct.c_ubyte),            
        ]
    if __name__ == "__main__":
        a = Data()
        print ct.sizeof(a)
as is show above.when i used this script running in python ,it prints 12.
but when running in Ironpython ,it is 14.
in fact ,i tried it in c like that:

    #include<stdio.h>
    void main()
    {
    #pragma pack(2)
 struct{
  unsigned char a;
  unsigned char b;
  unsigned char c;
  unsigned short d;
  unsigned int e;
  unsigned char f;
 }A;
    #pragma pack()
 printf("%d\n",sizeof(A));
    }
it is 12.

can you tell me why it is and how i can crrect it in Ironpython???
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
West, Peter | 30 Dec 18:15 2014
Picon
Picon

Data_as

Hi

I need to pass a DLL a pointer to an array of pointers to c arrays of unsigned 16 bit integers.

I started to do this using data_as(POINTER( type ) on sub-arrays.  This caused access violations. When I
looked at what was in the pointer arrays I discovered that they all pointed to the same location.  After
poking around a bit is seems that the problem is not to do with using sub-arrays as I expected but with the way
in which I have approached the problem and I can't see what I'm doing wrong.  Here is a very simple example

from ctypes import POINTER, c_uint16
import numpy as  np

if __name__ == '__main__':

   pointerArrayType = POINTER( c_uint16 ) * 2      # an array of pointers type length 2
   pointers = pointerArrayType()                           # the actual array

   frame1 = np.zeros(( 100, 100 ), dtype = np.uint16, order = 'C' )   # Ensure C contiguous layout
   frame2 = np.zeros(( 100, 100 ), dtype = np.uint16, order = 'C' )

   pointers[ 0 ] = frame1.ctypes.data_as( POINTER( c_uint16 ))
   pointers[ 1 ] = frame2.ctypes.data_as( POINTER( c_uint16 ))

   print pointers[ 0 ]
   print pointers[ 1 ]

This prints 
<__main__.LP_c_ushort object at 0x00000000025132C8>
<__main__.LP_c_ushort object at 0x00000000025132C8>

This suggests that the data arrays for frame1 and frame2 are at the same location.  Clearly I've done
something wrong but can't see what.  

Any help would be gratefully received.
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
Koteswara Rao Ruvva | 22 Sep 07:34 2014
Picon

Array allocation

Hello All,

I have the following getData function in a DLL that allocates memory and fill its contents.

extern "C" __declspec(dllexport) int getData(int *data) {
int size = 20;
               data = (int*) malloc(size*sizeof(int));

for (int i = 0; i < size; i++) {
data[i] = i*i;
}

return size;
}


I have the following Python code to call the getData function:

       mydll = ctypes.cdll.Lo adLibrary('MathFuncs.dll')

       mydll.getData.argtypes = [ctypes.POINTER(ctypes.c_int)]
       mydll.getData.restype  = ctypes.c_int

       data = ctypes.POINTER(ctypes.c_int)
       size = mydll.getData(ctypes.POINTER(data))

When I execute, I get the following error:
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP_c_long instance instead of _ctypes.PyCPointerType

I am not able to figure out the mistake. Could someone please correct me.

Thanks
Kotesh


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
Jason Marshall | 14 Jun 14:41 2014
Picon

ctypes.windll.kernel32.GetProcAddress returns address of 0

Hello ctypes-users,

I am a novice at ctypes and C. I am trying to get the addresses of some methods in ddraw.dll (obsolete, I know) so that I may use them with pygame. When I run the script below to get the methods' addresses, ctypes.windll.kernel32.GetProcAddress gives me addresses of 0. Can you see something that I'm doing wrong?

I have tried this in Python 2.7 (32-bit) under Win 7 (64-bit) and Python 2.5 (32-bit) under Win XP (32-bit). I got the same result in both environments.

Thanks,
Jason

# coding: cp1252
# What I am trying to do:
#   http://www.nerdblog.com/2010/04/fun-vertical-sync-hack.html
#
# DirectDrawCreate function
#   http://msdn.microsoft.com/en-us/library/windows/desktop/gg426116%28v=vs.85%29.aspx
# IDirectDraw7::GetMonitorFrequency method
#   http://msdn.microsoft.com/en-us/library/windows/desktop/gg426148%28v=vs.85%29.aspx
# IDirectDraw7::GetScanLine method
#   http://msdn.microsoft.com/en-us/library/windows/desktop/gg426149%28v=vs.85%29.aspx
#
# DirectX headers
#   http://www.steve-oh.com/blog/index.php/directx-70a-sdk-download/
#
# scary GUID structure
#   https://code.google.com/p/pyglet/source/browse/pyglet/com.py
# scary pointer to a pointer
#   http://stackoverflow.com/questions/8638942/python-ctypes-pointer-to-pointer-to-structure

import ctypes
from ctypes import POINTER, WINFUNCTYPE, byref, c_int, c_char_p, c_void_p, windll, wintypes

DD_OK = 0

# Load DirectDraw DLL
ddraw_dll = windll.LoadLibrary("ddraw")

# Initialize DirectDraw with DirectDrawCreate
class GUID(ctypes.Structure):
    _fields_ = [
        ('Data1', ctypes.c_ulong),
        ('Data2', ctypes.c_ushort),
        ('Data3', ctypes.c_ushort),
        ('Data4', ctypes.c_ubyte * 8)
    ]

    def __init__(self, l=0x6C14DB80, w1=0xA733, w2=0x11CE, b1=0xA5, b2=0x21, b3=0x00, b4=0x20, b5=0xAF, b6=0x0B, b7=0xE5, b8=0x60): # IID_IDirectDraw
        self.Data1 = l
        self.Data2 = w1
        self.Data3 = w2
        self.Data4[:] = (b1, b2, b3, b4, b5, b6, b7, b8)

    def __repr__(self):
        b1, b2, b3, b4, b5, b6, b7, b8 = self.Data4
        return 'GUID(%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x)' % (
            self.Data1, self.Data2, self.Data3, b1, b2, b3, b4, b5, b6, b7, b8)

DirectDrawCreate = ddraw_dll.DirectDrawCreate
DirectDrawCreate.argtypes = [c_void_p, POINTER(POINTER(GUID)), c_void_p]
control = POINTER(GUID)()
result = DirectDrawCreate(None, byref(control), None)

print "DirectDrawCreate result (0 is DD_OK):", result
assert result == DD_OK, "DirectDraw did not initialize"

# Get GetMonitorFrequency function's address
windll.kernel32.GetProcAddress.argtypes = [c_void_p, c_char_p]
GetMonitorFrequency_addr = windll.kernel32.GetProcAddress(ddraw_dll._handle, "GetMonitorFrequency")
print "GetMonitorFrequency_addr", hex(GetMonitorFrequency_addr)

# Get GetScanLine function's address
GetScanLine_addr = windll.kernel32.GetProcAddress(ddraw_dll._handle, "GetScanLine")
print "GetScanLine_addr", hex(GetScanLine_addr)



------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
Rob Gaddi | 16 Apr 02:01 2014

Can't create small bitfields

I'm trying to build up bitfields that are smaller than the word size of
the machine, only 1 or 2 bytes.  Unfortunately, the smallest Structure
I can get is 4 bytes.  Any ideas on what I'm doing wrong?  OS is
x86_64 Ubuntu, Python is 2.7.4 or 3.3.1 with equal results.  Sample code
below.

---

from __future__ import print_function
from ctypes import *

class Struct(Structure):
    _pack_ = 1

Struct._fields_ = [
        ('low', c_uint, 4),
        ('high', c_uint, 4),
    ]

x = Struct(low = 1, high = 2)

print('Structure Size:', sizeof(Struct))
print('Instance Size:', sizeof(x))
print('Structure Fields:', Struct.low, Struct.high)
print('Instance Fields:', x.low, x.high)

arr = (c_uint8 * sizeof(x)).from_buffer(x)
print('Bytes:', ','.join('{0:02X}'.format(b) for b in arr))

---

$python_vme_mods$ python test_bitfield.py 
Structure Size: 4
Instance Size: 4
Structure Fields: <Field type=c_uint, ofs=0:0, bits=4> <Field
type=c_uint, ofs=0:4, bits=4> Instance Fields: 1 2
Bytes: 21,00,00,00

--

-- 
Rob Gaddi, Highland Technology
18 Otis St.
San Francisco, CA 94103
415-551-1700

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
Roberto Bouza | 3 Apr 20:15 2014
Picon

Compiling ctypes statically?

Hello,

I have a python binary compiled statically, when I try to do the same with ctypes (outside of python compilation using the tar.gz) I get error because is trying to build the .so instead of a .a

Sorry I'm a bit lost with this, but anyways here is the compilation flags:

$> LDFLAGS="-Wl,-no-export-dynamic -static-libgcc -static -ldl -L/usr/local/lib -L/usr/local/lib64 -lev" CPPFLAGS="-static -fPIC -I/usr/local/include" /usr/local/python-static/bin/python setup.py build

Here is the output:

/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.4.6/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
error: command 'gcc' failed with exit status 1

Any help will be appreciated.

Thanks.
--
Roberto Bouza Fraga.
www: http://www.robertobouza.com
t: http://twitter.com/bouzafr - <at> bouzafr
e: bouzafr <at> gmail.com
------------------------------------------------------------------------------
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
muhammad waseem sarwar | 12 Dec 07:44 2013
Picon

Regarding external binding of functions

Hi,

I am new to ctypes and I have a questions regarding external binding
of function using ctypes. The question is as follows,

Q. I have a simple library that uses function pointer of
hello_printf(const char *format, ...) in one of its API. While using
this library in C, I point the function pointer of hello_printf to
printf and code works seamlessly.
hello_printf is not the API but is used in the implementation of one
of the API's. The reason for this is that I want external application
using the library to provide implementation of printf to provide
flexibility and is common practice in C/C++.

I want to know that how I can achieve this external binding of
function pointer using ctypes i.e. point hello_printf() to printf in
python so on calling the API, it gets the right printf implementation.

I am not sure if I explained it well and I can post the code if there
is ambiguity in question.

Help would be highly appreciated and thanks in advance.

Regards,
Waseem

------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
Nicholas Earl | 29 Sep 00:53 2013
Picon

Return struct causes segfault

I'm struggling with returning a struct value using ctypes. Mainly, it keeps segfaulting when I try and get the values from the returned object. I have my python script setup like this:

import ctypes
import numpy as np
from numpy.ctypeslib import ndpointer


class PhotoInfo(ctypes.Structure):
    _fields_ = [
        ('times', ctypes.POINTER(ctypes.c_double)),
        ('fluxes', ctypes.POINTER(ctypes.c_double)),
    ]


def main():
    lib = ctypes.cdll.LoadLibrary('cfile.so')

    start = lib.start
    start.restype = ctypes.POINTER(PhotoInfo)
    start.argtypes = [
        ctypes.c_int,
        ndpointer(ctypes.c_double),
    ]

    N = 3
    mass = np.array([0.00020335520, 5.977884E-05, 9.320397E-08])

    phin = start(N, mass)

    print phin[0].times[0]


And in my c file:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

typedef struct {
  double *times;
  double *fluxes;
} PhotoInfo;

extern "C" {
  PhotoInfo *start(int N, double *mass);
}

PhotoInfo *start(int N, double *mass) {
  PhotoInfo phin;
  vector<double> times;
  vector<double> fluxes;

// Here, I read in a file and fill times and fluxes with doubles using
// times.push_back(t) and fluxes.push_back(f)\

  phin.times = &times[0];
  phin.fluxes = &times[0];
  return &phin;
}


Any guidance on this would be greatly appreciated!

Nicholas Earl
Graduate Research Assistant
San Diego State University
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
Mathias Legerer | 27 Sep 13:33 2013
Picon

Accessing Array in Struct

Hi, I have a Struct in C defined like this:

typedef struct _xmySTRUCT
   {

   char   chSomeChar;
   <...>
   double dProperty[ 10];
   double dProptype[ 10];
   char   szPropname[ 10][  21];
   <...>
   } xmySTRUCT, *PxmySTRUCT;


In Python I defined the struct like this:
class MyStructPy(Structure):
   _fields_ = [   ("somechar"           , c_char                          )
                , ("property"           , c_double                  *  10 )
                , ("proptype"           , c_double                  *  10 )
                , ("propname"           , c_char * 21               *  10 )
]


I let my C-Applicatino load Data in the struct and then I try to read out the values in Python.
When I try to access the array of doubles, I get some incorrect values (e.g.
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
2705755772498316500000000000000000000000.000000
2706128776157293300000000000000000000000.000000
2705755777574079800000000000000000000000.000000
0.000000

And strangely the Values in Char-Array all seem to miss the first character.
Thats why I think the problem has something to do with pointers?

I have several such structs in C without Arrays of doubles or Char-Arrays and they work fine, but these arrays make problems.
Can somebody point me in the direction, what I do wrong?

Thank you,
Mathias
 
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
Nicholas Earl | 27 Sep 06:37 2013
Picon

Help with struct arrays

Hello all! I'm having difficulties accessing the information in a returned struct object. I'm quite new to C/C++, but I've had plenty of experience with C#, so I think I have my foot in the door.

I have a struct defined as

class PhotoInfo(ctypes.Structure):
    _fields_ = [
        ('times', ctypes.POINTER(ctypes.c_double)),
        ('fluxes', ctypes.POINTER(ctypes.c_double)),
    ]


with the restype defined like

def main():
    lib = ctypes.cdll.LoadLibrary('photoroutine.so')

    start = lib.start
    PhotoInfoPtr = ctypes.POINTER(PhotoInfo)
    start.restype = PhotoInfoPtr


But when I call

phin = start()

I can't get to the time and flux info the returned object has. I've tried using

phin.contents.times

but it just gives me a location; i.e. <__main__.LP_c_double object at 0x159fef0>

How do I get the actual array of times and fluxes?

Thanks for your time!

Nicholas Earl
Graduate Research Assistant
San Diego State University
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users

Gmane