2013-12-23 66 views
1

我一直在欺騙與ctypes的和所遇到的兩個問題:ctypes的:初始化數組的數組,並傳遞給C函數

問題1.我想建立一個cellComplex使用double*數組,但我想要new_cellComplex接受double*的數組(以及size_t參數),而不是固定數量的double*。具有固定數量的代碼看起來像這樣(和它運行良好)

extern "C" { 
    void * new_cellComplex(double* p_x, double* p_y, double* p_z) { 

    std::vector< std::pair<double,double> > point; 
    point.push_back(std::make_pair(p_x[0],p_x[1])); 
    point.push_back(std::make_pair(p_x[0],p_x[1])); 
    point.push_back(std::make_pair(p_x[0],p_x[1])); 

    cellComplex<double>* cmplx = new cellComplex<double>(point); 
    return cmplx; 
    } 

與Python代碼:

import ctypes 

cellComplex_lib = ctypes.cdll.LoadLibrary('./cellComplex_lib.so') 
cellComplex_lib.new_cellComplex.restype = ctypes.c_void_p 
cellComplex_lib.new_cellComplex.argtypes = [ctypes.c_double*2, 
              ctypes.c_double*2, 
              ctypes.c_double*2] 

p_x = (ctypes.c_double*2)(0.0,1.0) 
p_y = (ctypes.c_double*2)(0.0,1.0) 
p_z = (ctypes.c_double*2)(0.0,1.0) 

cmplx = cellComplex_lib.new_cellComplex(p_x,p_y,p_z) 

我寧願有以下(其中出現segfaults)

extern "C" { 
    void * new_cellComplex(double** p, size_t dim) { 

    std::vector< std::pair<double,double> > point; 
    for (size_t i=0; i<dim; ++i) { 
     point.push_back(std::make_pair(p[i][0],p[i][1])); 
    } 
    cellComplex<double>* cmplx = new cellComplex<double>(point); 
    return cmplx; 
    } 
} 

與Python代碼:

import ctypes 

dim = 3 
cellComplex_lib = ctypes.cdll.LoadLibrary('./cellComplex_lib.so') 
cellComplex_lib.new_cellComplex.restype = ctypes.c_void_p 
cellComplex_lib.new_cellComplex.argtypes = [(ctypes.c_double*2)*dim, 
              ctypes.c_size_t] 

p_x = (ctypes.c_double*2)(0.0,1.0) 
p_y = (ctypes.c_double*2)(0.0,1.0) 
p_z = (ctypes.c_double*2)(0.0,1.0) 

p = ((ctypes.c_double*2)*dim)(p_x,p_y,p_z) 

cmplx = cellComplex_lib.new_cellComplex(p,dim) 

^這不起作用,我不知道爲什麼。

問題2:(這裏包括,因爲它是在問題怒視)我從我C代碼返回基本上匿名的指針!這只是感覺,很好,很骯髒,而且必須有更好的方式來返回自定義數據類型並在Python中處理它。爲了記錄在案,我非常感謝this stackoverflow answer在那裏我學到這樣的巫術 - 但我不打算要能只要在晚上睡覺,因爲它是在我的代碼...

回答

2

相反的double **,使用double [][2]。你傳遞一個連續的C數組,你想訪問它作爲指向一行2個項目的指針。第一個索引是行索引。

聲明的陣列作爲double **是一個指向double指針,所以p[i]是一個指針,並再次p[i][0]解除引用它。但是根據你的數據,p[i]是一個偶然的指針NULL

參考comp.lang.c常見問題,question 6.18:當我通過一個二維數組期待 指針的指針的函數我的編譯器抱怨。

返回類型,你也可以繼承c_void_p,或使用鉤from_param_as_parameter_section 15.17.1.7最後一段在ctypes的文檔。