我已经编写了一个函数来修剪 C++ 中字符串中的空格,我希望从另一个文件中调用它。整个过程是使用 Cython 包装器从 Python 脚本调用的
如果我不在main.cpp中调用trim,程序就会运行;如果这样做,我会收到运行时错误
Traceback (most recent call last):
File "/home/jeff/projects/c/bfg/trim_test/trim_test.py", line 1, in <module>
import trim_binder
ImportError: ./libmain.so: undefined symbol: _Z4trimRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
对代码量表示歉意;我已经尽可能地修剪它了。可以用
克隆它git clone https://[email protected]/psionman/test_trim.git
main.h
#ifndef TEST_TRIM_H
#define TEST_TRIM_H
#include <iostream>
std::string testTrim(std::string);
#endif
main.cpp
#include <iostream>
#include "trim.h"
std::string testTrim(std::string line) {
std::string trimmed {};
trimmed = line;
trimmed = trim(line);
return trimmed;
}
修剪.h
#ifndef TRIM_STRINGS_H
#define TRIM_STRINGS_H
std::string& trim(std::string& s);
#endif
修剪.cpp #包括 #include“trim.h”
// trim from left
inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v")
{
s.erase(0, s.find_first_not_of(t));
return s;
}
// trim from right
inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v")
{
s.erase(s.find_last_not_of(t) + 1);
return s;
}
// trim from left & right
inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v")
{
return ltrim(rtrim(s, t), t);
}
trim_test.py
import trim_binder
line = ' AAA BB CC E '
trimmed = trim_binder.get_trimmed_text(line)
print(f'In trim_test: {trimmed.replace(" ", ".")}')
trim_wrapper.pyx
from libcpp.string cimport string
cdef extern from 'main.h':
string testTrim(char* input_text)
def get_trimmed_text(path):
input_text = str.encode(str(path))
py_bytes_object = input_text
cdef string s = py_bytes_object
raw_trimmed = testTrim(py_bytes_object)
trimmed = raw_trimmed.decode()
return trimmed
编译使用invoke包
任务.py 导入调用
WRAPPER_NAME = 'trim_wrapper.cpp'
BINDER = 'trim_binder' # .pyx file name
C_FILE = 'main'
compile_files = ['main', 'trim']
@invoke.task()
def build_c_function(c):
"""Build the shared library for the sample C++ code"""
files = [file + '.cpp' for file in compile_files]
files_str = ' '.join(files)
invoke.run(
f'g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC {files_str} '
'-I . '
f'-o lib{C_FILE}.so '
)
print('c function build complete')
def compile_python_module(cpp_name, extension_name):
invoke.run(
'g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC '
'`python3 -m pybind11 --includes` '
'-I . '
'{0} '
'-o {1}`python3-config --extension-suffix` '
f'-L. -l{C_FILE} -Wl,-rpath,.'.format(cpp_name, extension_name)
)
@invoke.task(build_c_function)
def build_cython(c):
"""Build the cython extension module"""
invoke.run(f'cython --cplus -3 {BINDER}.pyx -o {WRAPPER_NAME}')
compile_python_module(WRAPPER_NAME, BINDER)
print('cython build complete')
这是 libmain.so
的符号列表 w __cxa_finalize@GLIBC_2.2.5
w __gmon_start__
U __gxx_personality_v0@CXXABI_1.3
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U _Unwind_Resume@GCC_3.0
0000000000001140 T _Z8testTrimNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_disposeEv@GLIBCXX_3.4.21
U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_assignERKS4_@GLIBCXX_3.4.21
U _ZSt21ios_base_library_initv@GLIBCXX_3.4.32
并且这是 **trim_binder.cpython-311-x86_64-linux-gnu.so 符号列表的链接 ** 相当长
在
main.cpp
中,您没有包含标准库头文件<string>
(这是字符串定义所在的位置)。您包括 <iostream>
。这很可能包括 <string>
中的 some,但可能不是全部,并且某些位可能仅被前向声明。
我不确定这是否是完整的问题,但这肯定是一个错误。