gpt4 book ai didi

c++ - Cython:共享对象中的 undefined symbol

转载 作者:行者123 更新时间:2023-11-30 02:19:48 24 4
gpt4 key购买 nike

我在 python 项目中导入 c++ 代码,一切似乎都编译得很好但是当导入我的 .pyx 时我得到:

from AGCython import *
ImportError: /path/to/shared/object/AGCython.cpython-36m-x86_64-linux-gnu.so: undefined symbol: c_Stat_GetMeanAndVariance_double

在我的 AGCython.pyx 中我有:

cdef extern void c_Stat_GetMeanAndVariance_double (double* array, int nSize, double* mean, double* var)

及其 python 包装器

def Stat_GetMeanAndVariance_double(np.ndarray[double, ndim=1, mode="c"] input not None):
cdef int m #nSize
m = input.shape[0]
cdef double mean, var
c_Stat_GetMeanAndVariance_double(&input[0], m, &mean, &var)
return mean, var

这个cpp函数定义在AGc.cpp中:

#include "AGc.h"
void c_Stat_GetMeanAndVariance_double(const double *aData, const int nSize, double &mean, double &var)
{
// Special case, small vector
if (nSize<=1)
{
var= 0;
if (nSize)
mean= *aData;
else
mean= 0;
return;
}

double s, ssqr;
Stat_GetSums_double(aData, nSize, s, ssqr);

mean= s/nSize;
var= Stat_GetVariance(s, ssqr, nSize);
return;
}

并且AGc.h包含:

void c_Stat_GetMeanAndVariance_double(const double *aData, const int nSize, double &mean, double &var);

我的编译脚本是这样的:

from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
import numpy


sourcefiles = ['AGCython.pyx', 'AGc.cpp']

extensions = [Extension("AGCython", sourcefiles)]

setup(
ext_modules = cythonize(extensions, annotate=True)
)

这会导致此 gcc 调用:

gcc -pthread -B /home/ludvig/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/ludvig/anaconda3/include/python3.6m -c AGc.cpp -o build/temp.linux-x86_64-3.6/AGc.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
g++ -pthread -shared -B /home/ludvig/anaconda3/compiler_compat -L/home/ludvig/anaconda3/lib -Wl,-rpath=/home/ludvig/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.6/AGCython.o build/temp.linux-x86_64-3.6/AGc.o -o /path/to/my/project/AGCython.cpython-36m-x86_64-linux-gnu.so

我不明白我在这里错过了什么,我不认为警告是阅读 this 的问题问题

最佳答案

您的问题是名称修改。然而,它不起作用的原因有两个。

第一

AGCython.pyx 默认使用没有名称修改的 C 语言,即它期望符号的名称为 c_Stat_GetMeanAndVariance_double

附加文件是 *.cpp,因此 gcc 决定将其编译为 C++ 源代码,这意味着名称修改开始,相应的符号名称变为 _Z32c_Stat_GetMeanAndVariance_doublePKdiRdS1_ 。因此在寻找未损坏的名称时,加载程序会在运行时失败。

有不同的方法来修复它,但如果您打算使用 c++,最简单的方法是将 language='c++' 添加到您的设置中:

extensions = [Extension("AGCython", 
sourcefiles,
language='c++')]

第二:

您将导出的函数声明为:

cdef extern void c_Stat_GetMeanAndVariance_double (...)

是从cython翻译过来的

__PYX_EXTERN_C DL_IMPORT(void) c_Stat_GetMeanAndVariance_double(...);

__PYX_EXTERN_C 是一个定义:

#ifndef __PYX_EXTERN_C
#ifdef __cplusplus
#define __PYX_EXTERN_C extern "C"
#else
#define __PYX_EXTERN_C extern
#endif
#endif

这意味着它关闭了 C++ 案例的名称修改。为避免这种情况,您需要像通常那样在 header 中包含函数:

cdef extern from "AGc.h":
void c_Stat_GetMeanAndVariance_double(...)

关于c++ - Cython:共享对象中的 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50388605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com