使用 numpy 和 gdal 的 Python C 扩展在运行时给出未定义的符号
Posted
技术标签:
【中文标题】使用 numpy 和 gdal 的 Python C 扩展在运行时给出未定义的符号【英文标题】:Python C Extension using numpy and gdal giving undefined symbol at runtime 【发布时间】:2016-01-25 17:40:21 【问题描述】:我正在为 python 编写一个 C++ 扩展来加速内部创建的光栅图像查看器。 我有工作代码,但注意到速度并没有增加那么多,在深入分析后意识到这是由于 gdal.ReadAsArray 调用,这是来自 C 扩展的 python 回调。 为了在调用 python 对象时绕过 Python C-API 的开销,我决定将 C++ 库用于 gdal,而不是对现有 gdalDataset 使用 Python 回调。 (空间不是问题)。 然而,在实现了这个代码之后,我在运行时遇到了一个错误(扩展编译得很好)
这是
import getRasterImage_new
ImportError: /local1/data/scratch/lib/python2.7/site-packages
/getRasterImage_new.so: undefined symbol: _ZN11GDALDataset14GetRasterYSizeEv
下面的代码复制了错误(可能需要在您的机器上运行一些编辑(忽略未初始化的变量,这正是复制错误所需要的)。
Python:
#!/usr/bin/env python
import numpy
from osgeo import gdal
import PythonCTest
print("test starting")
PythonCTest.testFunction(1)
print("test complete")
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;
非常欢迎任何建议。
编辑
您还可以删除 from osgeo import gdal 并发生错误(只是刚刚注意到)。
编辑 2
我忘了说我正在使用 distutils 编译我的扩展
当前 setup.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'])])
【问题讨论】:
创建扩展时,链接命令中有-lgdal
吗?
我没有,我有-Igdal
,刚刚尝试过-lgdal
,没有任何变化
将libraries=['gdal']
添加到Extension
构造函数调用以确保gdal
用于链接模块(而不是仅用于编译)。
哇哇,这工作.. 谢谢,不敢相信我没有早点尝试过。这个扩展有很多问题。谢谢。如果你把它作为答案,我会标记它。
【参考方案1】:
Python 扩展模块是一个可动态加载(共享)的库。链接共享库时,您需要指定其库依赖项,例如-lgdal
和-lpython2.7
。否则会导致库中包含未解析的符号,如果在加载时未提供这些符号,则加载将失败,正如 Python 所报告的那样。
要解决该错误,您需要将libraries=['gdal']
添加到Extension
构造函数。在extra_compile_args
中指定-lgdal
将不起作用,因为编译参数,顾名思义,用于编译而不是链接。
请注意,在链接可执行文件时不会检测到未解析的符号,其中构建会因链接器错误而失败。要在链接共享库时获得相同的诊断信息,请在链接参数中包含 -Wl,-zdefs
。
【讨论】:
以上是关于使用 numpy 和 gdal 的 Python C 扩展在运行时给出未定义的符号的主要内容,如果未能解决你的问题,请参考以下文章
Python遥感图像处理应用篇(十八):GDAL +numpy对遥感图像归一化处理
Python遥感图像处理应用篇(二十三):Python+GDAL 批量拼接图像
Python遥感图像处理应用篇(二十三):Python+GDAL 批量拼接图像
Python GDAL+numpy遥感图像处理过程中背景像元处理方法