通过ctypes在c++项目上添加python接口。 OSError:./libfastbn.so:未定义的符号

问题描述 投票:0回答:1

我想在一个大型c++项目上添加一个简单的python接口,以便我可以使用python调用一些c++函数。这是一个大型的c++项目,结构如下

FastBN
  -src
    // many source files inside
  -include
    // many header files inside
  -lib
  CMakeLists.txt

对于我的第一次尝试,我刚刚在

include
中创建了一个新的头文件,在
src
中创建了一个源文件:

// test.h
extern "C" {
    int add(int n1, int n2);
}
// test.cpp
#include "test.h"
int add(int n1, int n2) {
    return n1 + n2;
}

构建后,我生成了

libfastbn.so
。然后我尝试了一个简单的 python 脚本:

import ctypes

mylib = ctypes.CDLL('./libfastbn.so')

mylib.add.argtypes = [ctypes.c_int, ctypes.c_int]
mylib.add.restype = ctypes.c_int

v1= 32
v2= 121

c = mylib.add(v1, v2)
print(c)

但是运行python脚本时出现以下错误。

Traceback (most recent call last):
  File "/home/jjt/work/BN/FastBN/build/python_interface.py", line 3, in <module>
    mylib = ctypes.CDLL('./libfastbn.so')
  File "/home/jjt/anaconda3/lib/python3.9/ctypes/__init__.py", line 382, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: ./libfastbn.so: undefined symbol: _ZNK8tinyxml27XMLNode17FirstChildElementEPKc

.so
文件是通过CMakeLists.txt生成的,我也在下面附上了它。然而,这是针对整个 C++ 项目的。

cmake_minimum_required(VERSION 3.10)
project(BayesianNetwork)

add_definitions("-Wall -g")

set(CMAKE_CXX_STANDARD 14)
#set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")

option(USE_MPI "option for mpi" OFF)
if (USE_MPI)
    message("Use MPI")
    add_definitions(-DUSE_MPI)
    find_package(MPI REQUIRED)
    include_directories(SYSTEM ${MPI_INCLUDE_PATH})
endif ()

include_directories(${PROJECT_SOURCE_DIR}/lib/tinyxml2)
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/lib/ARFF/src)
include_directories(${PROJECT_SOURCE_DIR}/lib/stats/include)
include_directories(${PROJECT_SOURCE_DIR}/lib/gcem/include)

add_subdirectory(lib)
add_subdirectory(src/fastbn)
add_subdirectory(src/test)

file(GLOB_RECURSE SRC src/fastbn/*.cpp)
file(GLOB HEAD include/*.h)

add_library(fastbn SHARED ${SRC} ${HEAD})

add_executable(BayesianNetwork ${SRC} ${HEAD})
target_link_libraries(BayesianNetwork tinyxml2 ARFF stats gcem)
target_link_libraries(BayesianNetwork ${MPI_C_LIBRARIES})
python c++ ctypes
1个回答
0
投票

使用 ctypes 返回的未定义符号错误可能是加载程序失败的结果。

建议对非标准位置的库使用绝对路径,相对路径可能有效也可能无效,具体取决于操作系统品牌。

import ctypes;
import pathlib;


mylib_path = pathlib.Path(__file__).absolute() / "libfastbn.so"
mylib = ctypes.CDLL(mylib_path)

至于加载每个库,如果所有依赖项都位于标准位置或 LD_LIBRARY_PATH,则无需重新实现动态链接器功能,您可能需要使用 LD_DEBUG 进行诊断:https://tldp.org/HOWTO/程序库-HOWTO/shared-libraries.html#AEN77

© www.soinside.com 2019 - 2024. All rights reserved.