SWIG错误:未定义的符号

3

我在使用swig时遇到了问题,根据信息显示我的代码中有一个数据成员是未定义的符号。我已经在网上找到了如何修复函数的答案,但这个问题让我困惑。

我的错误信息是:

Traceback (most recent call last):
  File "./test1.py", line 5, in <module>
    from volumes import *
  File "/scratch/rjkern/projects/RJKERN_volrend/scripts/volumes.py", line 26, in <module>
    _volumes = swig_import_helper()
  File "/scratch/rjkern/projects/RJKERN_volrend/scripts/volumes.py", line 22, in swig_import_helper
    _mod = imp.load_module('_volumes', fp, pathname, description)
ImportError: /scratch/rjkern/projects/RJKERN_volrend/scripts/_volumes.so: undefined symbol: _ZN13ConstantColorC1ESt10shared_ptrI5ColorE

这是我的代码:

/*
 *  ColorOperations.h
 */

#ifndef ___COLOROPS___
#define ___COLOROPS___

#include "Color.h"
#include "ProgressMeter.h"
#include "Vector.h"
#include "Volume.h"
#include "VolumeOperations.h"

#include <memory>

using namespace std;

class ConstantColor : public Volume<Color>{
    shared_ptr <Color> color;

public:
    ConstantColor(const shared_ptr<Color>& _color);

    const Color eval(const Vector& P) const;
    Color grad(const Vector& P);
};
#endif

并且:

/*
 *  ColorOperations.cpp
 */

#include "ColorOperations.h"

ConstantColor::ConstantColor(const shared_ptr<Color>& _color){
    color = _color;
}

const Color ConstantColor::eval(const Vector& P)const{
    return *color;
}
1个回答

17
我们可以使用来还原符号名称。
c++filt _ZN13ConstantColorC1ESt10shared_ptrI5ColorE

这给出了:

ConstantColor::ConstantColor(std::shared_ptr<Color>)

即您的构造函数需要一个shared_ptr。但只会报告第一个未解决的符号。

请注意这里不是引用,但是您的构造函数看起来像是需要引用。您的.i或其他文件中可能有拼写错误,这可能解释了为什么某些东西认为存在非引用版本。

另一个可能的解释是,您已经将包装器(即编译volumes_wrap.cxx)构建为共享对象,但未将已编译的ColourOperations.cpp链接到该对象。

或者,如果您已经链接了它,那么可能链接顺序不正确,因此被链接器视为不需要。如果是这种情况,请确保在链接器命令行上最后使用-lcolour_library/colour_library.a/ColorOperatios.o。(那里的名称是猜测的)。


2
感谢您提供 c++filt 的提示。太棒了! - jorgeca
我来晚了,但我遇到了同样的问题。当我不使用SWIG时,我的CPP代码运行良好,但当我使用SWIG并尝试运行Python脚本时,会出现“未定义符号”错误。你能详细解释一下“你已经将包装器构建为共享对象,但没有将编译的ColourOperations.cpp链接到该对象”吗?此外,在你提供的链接中,我不理解第三个gcc命令行在做什么。对于我的情况,我只执行类似前两个命令行的操作。 - Alex Eastman
通常情况下,您最终会得到两个共享库。首先是您实际想要包装的库。其次是目标语言需要作为语言扩展加载的共享对象库,即swig位。某些东西需要确保加载语言扩展程序时加载它正在包装的真正库,否则您将会遇到类似这样的错误。这可以通过几种方式来完成,如果您要包装的库是静态的,则正确链接即可。如果它也是一个共享库,那么您也可以再次链接它。或者您可以手动使用dlopen。 - Flexo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接