AttributeError:python:未定义符号:使用 ctypes 从 Python 访问 C++ 函数时

Posted

技术标签:

【中文标题】AttributeError:python:未定义符号:使用 ctypes 从 Python 访问 C++ 函数时【英文标题】:AttributeError: python: undefined symbol: when accessing C++ function from Python using ctypes 【发布时间】:2015-11-25 04:11:38 【问题描述】:

我想要做的是从 Python 调用 C++ 方法来返回一个二维数组。 Python 文件名是:BaxterArm1.py,C++ 文件名是:baxIK.cpp。以下是我如何编译我的 c++ 程序:

g++ -c -fPIC baxIK.cpp -o baxIK.o
g++ -shared -Wl,-soname,baxIK.so -o baxIK.so baxIK.o

下面是C++程序的相关部分:

int main(int argc, char** argv)




extern "C" float** compute(float x, float y, float z, float q1, float q2, float q3, float q4)

    unsigned int num_of_solutions = (int)solutions.GetNumSolutions();
    std::vector<IKREAL_TYPE> solvalues(num_of_joints);
    float** sols;
    sols = new float*[(int)num_of_solutions];

    for(std::size_t i = 0; i < num_of_solutions; ++i) 
        sols[i] = new float[7];
        for( std::size_t j = 0; j < solvalues.size(); ++j)
        
            printf("%.15f, ", solvalues[j]);
            sols[i][j] = solvalues[j];
        
        printf("\n");
       
    return sols;

这个想法是返回一个 Nx7 数组供 Python 接收。 Python代码如下:

def sendArm(xGoal, yGoal, zGoal, right, lj):
print "Goals %f %f %f" % (xGoal, yGoal, zGoal)
output = ctypes.CDLL(os.path.dirname('baxIK.so'))
output.compute.restype = POINTER(c_float)
output.compute.argtypes = [c_float, c_float, c_float, c_float, c_float, c_float, c_float]   
res = output.compute(xGoal, yGoal, zGoal, 0.707, 0, 0.7, 0)
print(res)

我得到的错误在线

output.compute.restype = POINTER(c_float)

回溯如下:

File "/home/eadom/ros_ws/src/baxter_examples/scripts/BaxterArm1.py", line 60, in sendArm
    output.compute.restype = POINTER(c_float)
  File "/usr/lib/python2.7/ctypes/__init__.py", line 378, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib/python2.7/ctypes/__init__.py", line 383, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: python: undefined symbol: compute

我对如何解决这个问题感到困惑。另外,有人可以对此进行检查,看看我是否正确发送了二维数组?因为它只是发送一个一维数组,但我在发送一个二维数组时找不到任何东西。感谢您的帮助。

【问题讨论】:

返回类型是指向指针的指针。你试过output.compute.restype = POINTER(POINTER(c_float)) 是的,我会改变的。谢谢你。但这并不能解决其他问题 您使用的是 extern "C",因此不应将其命名为错误名称。检查“compute”是否列在objdump -T baxIK.so 中,即在dlsym 查找它的动态符号表中。 我就是这么做的。计算显示一次,但终端的整体输出太长,终端无法容纳。还有其他建议吗? objdump -T baxIK.so | grep compute 【参考方案1】:

终于搞定了!问题是 (os.path.dirname('baxIK.so') 正在返回一个空字符串,所以我放入了完整目录。我通过使用 llapack 编译 g++ 解决了我之前提到的另一个问题,现在我正在修复最后一个细节。我希望这对其他人有帮助。

【讨论】:

在 POSIX 系统上 CDLL('') 引用主模块。由于未定义符号错误,我什至没有注意到您错误地使用了dirname。如果文件与脚本/模块在同一目录下,可以使用scriptdir = os.path.abspath(os.path.dirname(__file__));libpath = os.path.join(scriptdir, 'baxIK.so')

以上是关于AttributeError:python:未定义符号:使用 ctypes 从 Python 访问 C++ 函数时的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“功能”对象没有属性“predict_classes”

sklearn管道适合:AttributeError:未找到下限

python框架fastapi, AttributeError: module 'asyncio' has no attribute 'iscoroutinefunction&

AttributeError:模块“tensorflow”没有属性“app”

Python错误:AttributeError: 'generator' object has no attribute 'next'解决办法

Python 脚本报错AttributeError: 'module 'yyy' has no attribute 'xxx'的解决方法