c++ - 修复使用第三方库 (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++ 的新手。
解决此类问题的正确方法是什么?我认为从我给出的大纲中应该清楚上下文,但如果需要更多,请告诉我!谢谢你。
解决方案
这不是你的错;它看起来像是那个 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
,因此也可以将互斥锁声明移动到该模板中。不过,我还没有检查过这是否会破坏任何东西。
推荐阅读
- python - 将数据作为每行的列附加到文件(Python)
- spring - SimpleAsyncTaskExecutor 的最大线程大小是多少?- 春季批次
- javascript - 使用 fetch() 发送带有正文表单数据的发布请求
- godot - Godot Engine 2D如何实现对象的可见区域?
- javascript - 为什么在这种情况下,currying 函数的工作方式与 javascript 中的普通函数不同?
- solr - Solr如何将提升因子添加到双字段值
- php - 是否可以在 add-to-wishlist.php 文件中使用传递给启动短代码的值?
- android - 通过启动器搜索栏使 android 应用程序可搜索几个关键字
- python - 如何在 Python 的 PDFminer 中找到正则表达式?
- r - 如何使用循环对数据集进行统计汇总?