首页 > 解决方案 > 修复使用第三方库 (OpenGA) 时的多重定义错误

问题描述

我对 c++ 相当陌生,我正在使用这个项目作为学习经验。我在 Visual Studio 2019 中工作,我正在使用这个库

https://github.com/Arash-codedev/openGA

尝试解决一个版本的车辆路线问题。

在将我的代码重构为单独的类时遇到了一个问题,一旦它变得笨拙,包括单个 cpp 文件中的所有内容,尽管单个文件是 OpenGA 库示例中概述的方法。

目前,似乎导致问题的基本结构如下。

Algorithm.cpp

#include "Crossover.h"
#include "EvaluateSolution.h"
...
Crossover.h

#include "GeneticStructs.h
...
EvaluateSolution.h

#include GeneticStructs.h

...
GeneticStructs.h

#include openga.hpp

...

外部库具有以下定义:

openga.hpp

...
std::mutex mtx_rand;
...

GeneticStructs 只有 Chromosome 和 Gene 结构,每个结构都带有重载的 ostream 运算符。

问题是当我编译时,我得到以下链接器错误:

Crossover.obj : 错误 LNK2005: "class std::mutex EA::mtx_rand" (?mtx_rand@EA@@3Vmutex@std@@A) 已经在 Algorithm.obj 中定义

EvaluateSolution.obj : 错误 LNK2005: "class std::mutex EA::mtx_rand" (?mtx_rand@EA@@3Vmutex@std@@A) 已经在 Algorithm.obj 中定义

GeneticStructs.obj : 错误 LNK2005: "class std::mutex EA::mtx_rand" (?mtx_rand@EA@@3Vmutex@std@@A) 已经在 Algorithm.obj 中定义

因此,据我了解,我违反了单一定义规则。我想我明白为什么了。互斥锁在每个目标文件中单独定义,当链接器尝试合并目标文件时会导致歧义。当然,欢迎对实际错误进行说明,因为我是 C++ 的新手。

解决此类问题的正确方法是什么?我认为从我给出的大纲中应该清楚上下文,但如果需要更多,请告诉我!谢谢你。

标签: c++

解决方案


这不是你的错;它看起来像是那个 OpenGA 库中的一个错误。


正常的方法是将标头中的变量声明为:

extern std::mutex mtx_rand;

然后有一个(并且只有一个)源文件(例如OpenGA.cpp)在其中定义它,同时考虑到命名空间:

#include "OpenGA.hpp"
NS_EA_BEGIN
std::mutex mtx_rand;
NS_EA_END

当然,如果标头包含在一个(并且只有一个)源文件中,则不需要这样做,这可能是库的作者一直在使用它的方式。


由于互斥锁仅用于保护模板std::mt19937_64 rng内部Genetic,因此也可以将互斥锁声明移动到该模板中。不过,我还没有检查过这是否会破坏任何东西。


推荐阅读