ctypes: 初始化数组并传递给 C 函数

ctypes: Initialize array of arrays and pass to C function

我一直在玩 ctypes,遇到了两个问题:

问题 1. 我想使用 double* 数组构建一个 cellComplex,但我希望 new_cellComplex 接受一个 double*\\ 的数组(以及一个 size_t 参数),而不是一个固定数量的 double*\\'s。使用固定数字,代码看起来像这样(并且运行良好):

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;

 }
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)

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;

 }

}
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)

使用 Python 代码:

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;

 }
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)

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;

 }

}
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)

我宁愿有以下(段错误):

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;

 }
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)

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;

 }

}
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)

使用 Python 代码:

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;

 }
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)

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;

 }

}
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。(包括在此处是因为它在问题 1 中很明显)我正在从我的 C 代码返回一个本质上匿名的指针!这只是感觉,嗯,很脏,并且必须有更好的方法来返回自定义数据类型并在 Python 中处理它。作为记录,我非常感谢这个 stackoverflow 的答案,我在其中学到了这样的巫术 - 但只要它在我的代码中,我就无法在晚上睡觉......


使用 double [][2] 代替 double **。您正在传递一个连续的 C 数组,您希望将其作为指向一行 2 项的指针进行访问。第一个索引是行索引。

将数组声明为 double ** 是指向 double 指针的指针,因此 p[i] 是指针,而 p[i][0] 再次取消引用它。但是根据您的数据, p[i] 是一个 NULL 指针。

Refer to the comp.lang.c FAQ, question

6.18: My compiler complained when I passed a two-dimensional array to a function expecting a

pointer to a pointer.

对于返回类型,您可以继承 c_void_p,或者使用 ctypes 文档中第 15.17.1.7 节最后一段的钩子 from_param_as_parameter_


相关推荐

  • Spring部署设置openshift

    Springdeploymentsettingsopenshift我有一个问题让我抓狂了三天。我根据OpenShift帐户上的教程部署了spring-eap6-quickstart代码。我已配置调试选项,并且已将Eclipse工作区与OpehShift服务器同步-服务器上的一切工作正常,但在Eclipse中出现无法消除的错误。我有这个错误:cvc-complex-type.2.4.a:Invali…
    2025-04-161
  • 检查Java中正则表达式中模式的第n次出现

    CheckfornthoccurrenceofpatterninregularexpressioninJava本问题已经有最佳答案,请猛点这里访问。我想使用Java正则表达式检查输入字符串中特定模式的第n次出现。你能建议怎么做吗?这应该可以工作:MatchResultfindNthOccurance(intn,Patternp,CharSequencesrc){Matcherm=p.matcher…
    2025-04-161
  • 如何让 JTable 停留在已编辑的单元格上

    HowtohaveJTablestayingontheeditedcell如果有人编辑JTable的单元格内容并按Enter,则内容会被修改并且表格选择会移动到下一行。是否可以禁止JTable在单元格编辑后转到下一行?原因是我的程序使用ListSelectionListener在单元格选择上同步了其他一些小部件,并且我不想在编辑当前单元格后选择下一行。Enter的默认绑定是名为selectNext…
    2025-04-161
  • Weblogic 12c 部署

    Weblogic12cdeploy我正在尝试将我的应用程序从Tomcat迁移到Weblogic12.2.1.3.0。我能够毫无错误地部署应用程序,但我遇到了与持久性提供程序相关的运行时错误。这是堆栈跟踪:javax.validation.ValidationException:CalltoTraversableResolver.isReachable()threwanexceptionatorg.…
    2025-04-161
  • Resteasy Content-Type 默认值

    ResteasyContent-Typedefaults我正在使用Resteasy编写一个可以返回JSON和XML的应用程序,但可以选择默认为XML。这是我的方法:@GET@Path("/content")@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})publicStringcontentListRequestXm…
    2025-04-161
  • 代码不会停止运行,在 Java 中

    thecodedoesn'tstoprunning,inJava我正在用Java解决项目Euler中的问题10,即"Thesumoftheprimesbelow10is2+3+5+7=17.Findthesumofalltheprimesbelowtwomillion."我的代码是packageprojecteuler_1;importjava.math.BigInteger;importjava…
    2025-04-161
  • Out of memory java heap space

    Outofmemoryjavaheapspace我正在尝试将大量文件从服务器发送到多个客户端。当我尝试发送大小为700mb的文件时,它显示了"OutOfMemoryjavaheapspace"错误。我正在使用Netbeans7.1.2版本。我还在属性中尝试了VMoption。但仍然发生同样的错误。我认为阅读整个文件存在一些问题。下面的代码最多可用于300mb。请给我一些建议。提前致谢publicc…
    2025-04-161
  • Log4j 记录到共享日志文件

    Log4jLoggingtoaSharedLogFile有没有办法将log4j日志记录事件写入也被其他应用程序写入的日志文件。其他应用程序可以是非Java应用程序。有什么缺点?锁定问题?格式化?Log4j有一个SocketAppender,它将向服务发送事件,您可以自己实现或使用与Log4j捆绑的简单实现。它还支持syslogd和Windows事件日志,这对于尝试将日志输出与来自非Java应用程序…
    2025-04-161