Python C 扩展使用 numpy 和 gdal 在运行时给出未定义的符号
Python C Extension using numpy and gdal giving undefined symbol at runtime
我正在为 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
下面的代码复制了错误(可能需要进行一些编辑才能在计算机上运行(忽略未初始化的变量,这只是复制错误所需的变量)。
蟒:
#!/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 testFunctionn";
y->GetRasterYSize();
std::cout << "doing stuff" << "n";
return Py_None;
}
任何建议将非常受欢迎。
编辑
您也可以从osgeo导入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'])])
Python 扩展模块是一个可动态加载(共享)的库。链接共享库时,需要指定其库依赖项,例如-lgdal
,以及 -lpython2.7
。如果不这样做,会导致库具有未解析的符号,如果在加载时未提供这些符号,则加载将失败,如 Python 报告的那样。
若要解决此错误,需要将libraries=['gdal']
添加到构造函数Extension
。在extra_compile_args
中指定-lgdal
不起作用,因为顾名思义,编译参数用于编译而不是链接。
可执行文件时不会未检测到未解析的符号,其中生成将失败并显示链接器错误。要在链接共享库时获得相同的诊断,请在链接参数中包含-Wl,-zdefs
。
相关文章:
- 编译C++时未定义的引用
- 在 Mac 上使用 CMAKE 将 FFTW 和 FFTWPP 链接到项目中时未定义的符号
- 我可以在运行时重新定义在 OpenCascade/OCCT 标头中定义的 c++ 静态常量吗?
- 在编译时,C++项目抛出错误 C2228,这是预期的,因为控件在运行时未达到该点
- 删除动态数组时未定义标识符
- 调用 Win32 API 函数时未定义的引用
- 与共享库链接时未定义的引用
- 编译为目标 wasm 时未定义的符号
- 错误:基类在从基类父派生类 Son 时未定义
- 在 tensorflow-GPU 中使用用户运算符时未定义的符号>=1.15
- 在Mono-Pinvoke中尝试使用本机C++时未定义的符号
- ctypes,添加静态库时未定义的符号
- 尝试使用 MinGW/CMake 构建 GLFW 示例时未定义的引用
- 尝试使用 Cython 扩展时未定义的符号
- 使用 glew 和 mingw 时未定义的引用?
- 链接到 Boost 1.63 静态库时未定义的引用
- gtest –– 使用TEST_F时未定义的符号
- 在FreesWitch中使用AWS C SDK加载模块时未定义的符号错误
- 错误:(49) 在 Android 中使用 OpenCV 原生时未定义对'cv::Stitcher::createDefault(bool)'的引用
- 在另一台计算机中运行 GTKMM 代码时未定义的符号