On Tue, Nov 18 2014, Marco Giusti wrote:
> Salve a tutti,
> 
> con ctypes vorrei richiamare una funzione C che ritorna **char. La
> funzione in causa assegna la memoria per le singole stringhe e per
> l'array stesso e lascia al chiamante l'onere di liberarla. Sebbene con
> ctypes riesca ad accedere ai singoli valori, non riesco ad accedere
> all'area di memoria puntate e di conseguenza non riesco a liberarla.

Penso di aver risolto giocando con i puntatori come in C. Spero di non
andare all'inferno per questo .)

Per la cronaca allego quanto fatto così, se avete voglia, potete anche
verificare la correttezza.

m.
#include <stdlib.h>
#include <stdio.h>
#include "my.h"

int main(int argc, char *argv[])
{
	char **env = NULL;
	int i;

	if ((env = getlist()) == NULL) {
		perror("getlist");
		exit(1);
	}

	for (i=0; env[i] != NULL; i++)
		printf("%s\n", env[i]);
	exit(0);
}
all: libmy.so a.out

run: libmy.so
        LD_LIBRARY_PATH=. python my.py

libmy.so: my.c my.h
        gcc -Wall -fPIC -g -c my.c
        gcc -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 my.o
        ln -sf libmy.so.1.0 libmy.so.1
        ln -sf libmy.so.1 libmy.so

a.out: libmy.so main.c
        gcc -Wall -I. -L. -lmy -g main.c 

clean:
        rm my.o a.out libmy.so*
#include <stdlib.h>
#include <string.h>

char **getlist(void)
{
	char **env = NULL;

	if ((env = malloc(3 * sizeof(char *))) != NULL) {
		env[0] = NULL;
		env[1] = NULL;
		env[2] = NULL;
		if ((env[0] = strdup("hello")) != NULL) {
			if ((env[1] = strdup("world")) != NULL)
				return env;
			else
				free(env[0]);
		}
		free(env);
	}
	return NULL;
}
char **getlist(void);
import ctypes
import ctypes.util

_libmy = ctypes.CDLL("libmy.so.1")
_libc = ctypes.CDLL(ctypes.util.find_library("c"))
_sizeof_pointer = ctypes.sizeof(ctypes.c_void_p)


def getlist():
    arr = _libmy.getlist()
    ret = []
    off = 0
    p = ctypes.c_int.from_address(arr).value
    while p:
        ret.append(ctypes.string_at(p))
        _libc.free(p)
        off += _sizeof_pointer
        p = ctypes.c_int.from_address(arr + off).value
    _libc.free(arr)
    return ret

if __name__ == "__main__":
    print getlist()
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a