使用numpy和gdal在runtim提供未定义符号的Python C扩展

2024-10-01 02:36:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为Python写一个C++扩展,以加速在内部创建的光栅图像查看器。 我有一些工作代码,但是注意到速度没有增加太多,在深入分析之后,我意识到这是由于gdal.ReadAsArray公司调用,这是来自C扩展的python回调。 为了绕过Python C-API的开销,调用Python对象,我决定使用C++库来代替GDAL,而不是使用Python回调到现有的GDALADATSET。(空间不是问题)。 但是在实现了这个代码之后,我在运行时遇到了一个错误(扩展编译得很好)

那是

 import getRasterImage_new
 ImportError: /local1/data/scratch/lib/python2.7/site-packages
    /getRasterImage_new.so: undefined symbol: _ZN11GDALdataset14GetRasterYSizeEv

下面的代码复制了错误(可能需要一些编辑才能在您的计算机上运行(忽略未初始化的变量,这只是复制错误所需的内容)。在

Python:

^{pr2}$

C++:

#include "Python.h"
#include "numpy/arrayobject.h"
#include "gdal_priv.h"
#include <iostream>

extern "C"{
static PyObject* PythonCTest_testFunction(PyObject* args);
static PyMethodDef PythonCTest_newMethods[] = {
   {"testFunction", (PyCFunction)PythonCTest_testFunction, METH_VARARGS,
      "test function"},
   {NULL,NULL,0,NULL}};

PyMODINIT_FUNC initPythonCTest(void){
   (void)Py_InitModule("PythonCTest",PythonCTest_newMethods);
   import_array();
}
}
GDALDataset* y;
static PyObject* PythonCTest_testFunction(PyObject* args){
   std::cout << "in testFunction\n";
   y->GetRasterYSize();
   std::cout << "doing stuff" << "\n";
   return Py_None;
}

欢迎提出任何建议。在


编辑

您还可以从osgeo导入gdal中删除,然后发生错误stull(只是注意到了这一点)。在


编辑2

我忘了说我在用distutils编译我的扩展

当前设置.py是

#!/usr/bin/env python
from distutils.core import setup, Extension
import os
os.environ["CC"] = "g++"
setup(name='PythonCTest', version='1.0', \
   ext_modules=[Extension('PythonCTest', ['PythonCTest.cpp'],
   extra_compile_args=['--std=c++14','-l/usr/include/gdal', '-I/usr/include/gdal'])])

Tags: 代码import编辑includeusr错误argsstatic
1条回答
网友
1楼 · 发布于 2024-10-01 02:36:15

Python扩展模块是一个动态可加载(共享)的库。链接共享库时,需要指定它的库依赖项,例如-lgdal,为此,-lpython2.7。不这样做会导致库中包含未解析的符号,如果在加载时这些符号没有提供,则加载将失败,正如Python报告的那样。在

要解决此错误,需要将libraries=['gdal']添加到Extension构造函数中。在extra_compile_args中指定-lgdal将不起作用,因为顾名思义,编译参数用于编译而不是链接。在

请注意,在链接可执行文件时,未解析的符号不会不被检测到,在这种情况下,生成将因链接器错误而失败。要在链接共享库时获得相同的诊断,请在链接参数中包含-Wl,-zdefs。在

相关问题 更多 >