How to correctly pass “pointer-to-pointer” into DLL via ctypes?

G

Grigory Petrov

Hello.

I have a DLL that allocates memory and returns it. Function in DLL is like this:

void Foo( unsigned char** ppMem, int* pSize )
{
  * pSize = 4;
  * ppMem = malloc( * pSize );
  for( int i = 0; i < * pSize; i ++ ) (* pMem)[ i ] = i;
}

Also, i have a python code that access this function from my DLL:

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
Foo( byref( mem ), byref( size ) ]
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]

I'm expecting that print will show "4 0 1 2 3" but it shows "4 221 221
221 221" O_O. Any hints what i'm doing wrong?
 
D

Diez B. Roggisch

Grigory Petrov said:
Hello.

I have a DLL that allocates memory and returns it. Function in DLL is like this:

void Foo( unsigned char** ppMem, int* pSize )
{
  * pSize = 4;
  * ppMem = malloc( * pSize );
  for( int i = 0; i < * pSize; i ++ ) (* pMem)[ i ] = i;
}

Also, i have a python code that access this function from my DLL:

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
Foo( byref( mem ), byref( size ) ]
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]

I'm expecting that print will show "4 0 1 2 3" but it shows "4 221 221
221 221" O_O. Any hints what i'm doing wrong?

After correcting quite a few obvious errors in your code, it worked just
fine for me. So I guess what you think you test is not what you test.

--- test.py
from ctypes import *

foo = cdll.LoadLibrary("/Users/deets/projects/GH28/kinect/kinect/c/foo/libtest.dylib").foo
foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
foo( byref( mem ), byref( size ) )
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]
---

--- test.c
void foo( unsigned char** ppMem, int* pSize )
{
int i;
* pSize = 4;
* ppMem = malloc( * pSize );
for( i = 0; i < * pSize; i ++ ) (* ppMem)[ i ] = i;
}
---

--- CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (Test)
add_library(test SHARED test.c)
 
G

Grigory Petrov

Thank you a lot!

I have stripped down my production code to the sample - and it worked.
Bug was in another part of my code where free() was called for the
memory in question.

Grigory Petrov said:
Hello.

I have a DLL that allocates memory and returns it. Function in DLL is like this:

void Foo( unsigned char** ppMem, int* pSize )
{
  * pSize = 4;
  * ppMem = malloc( * pSize );
  for( int i = 0; i < * pSize; i ++ ) (* pMem)[ i ] = i;
}

Also, i have a python code that access this function from my DLL:

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
Foo( byref( mem ), byref( size ) ]
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]

I'm expecting that print will show "4 0 1 2 3" but it shows "4 221 221
221 221" O_O. Any hints what i'm doing wrong?

After correcting quite a few obvious errors in your code, it worked just
fine for me. So I guess what you think you test is not what you test.

--- test.py
from ctypes import *

foo = cdll.LoadLibrary("/Users/deets/projects/GH28/kinect/kinect/c/foo/libtest.dylib").foo
foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
foo( byref( mem ), byref( size ) )
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]
---

--- test.c
void foo( unsigned char** ppMem, int* pSize )
{
 int i;
 * pSize = 4;
 * ppMem = malloc( * pSize );
 for( i = 0; i < * pSize; i ++ ) (* ppMem)[ i ] = i;
}
---

--- CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (Test)
add_library(test SHARED test.c)
 
Z

zlchen.ken

Hello.

I have a DLL that allocates memory and returns it. Function in DLL is like this:

void Foo( unsigned char** ppMem, int* pSize )
{
  * pSize = 4;
  * ppMem = malloc( * pSize );
  for( int i = 0; i < * pSize; i ++ ) (* pMem)[ i ] = i;
}

Also, i have a python code that access this function from my DLL:

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
Foo( byref( mem ), byref( size ) ]
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]

I'm expecting that print will show "4 0 1 2 3" but it shows "4 221 221
221 221" O_O. Any hints what i'm doing wrong?

I am wondering in Python how you free the memory which is allocated in yourDLL ?
Thanks
 
Z

zlchen.ken

Hello.

I have a DLL that allocates memory and returns it. Function in DLL is like this:

void Foo( unsigned char** ppMem, int* pSize )
{
  * pSize = 4;
  * ppMem = malloc( * pSize );
  for( int i = 0; i < * pSize; i ++ ) (* pMem)[ i ] = i;
}

Also, i have a python code that access this function from my DLL:

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
Foo( byref( mem ), byref( size ) ]
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]

I'm expecting that print will show "4 0 1 2 3" but it shows "4 221 221
221 221" O_O. Any hints what i'm doing wrong?

I am wondering in Python how you free the memory which is allocated in yourDLL ?
Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top