Visual Studio 中的链接器错误
Linker errors in Visual Studio
我正在编写一个 C++ wxWidgets 计算器应用程序。我有这个头文件,我在其中声明我的应用程序支持的各种操作和常量。当我尝试编译时,出现 258 LNK2005 错误,例如:
Error LNK2005 "bool __cdecl isBinary(class wxString)"
(?isBinary@@YA_NVwxString@@@Z) already defined in
app.obj C:\Users\giorg\Desktop\Visual
Studio\wxWidgetsTest\wxWidgetsTest\events.obj 1 ikeCalculator
Error LNK2005 "class wxString unary::tan" (?tan@unary@@3VwxString@@A)
already defined in app.obj C:\Users\giorg\Desktop\Visual
Studio\wxWidgetsTest\wxWidgetsTest\events.obj 1 ikeCalculator
此文件中的所有内容依此类推。每次在其他文件中引用这些对象之一时似乎都会出错。
#pragma once
#include "wx/wx.h"
#include <cmath>
#include <map>
namespace binary {
wxString add(L"+"), sub(L"-");
wxString mul(L"\u00D7"), div(L"\u00F7");
wxString pow(L"^");
}
namespace unary {
wxString sqrt(L"\u221A");
wxString sin(L"sin"), cos(L"cos"), tan(L"tan");
wxString arcsin(L"arcsin"), arccos(L"arccos"), arctan(L"tan");
}
namespace constant {
wxString pi(L"\u03C0");
wxString light_speed(L"c");
wxString avogadro_number(L"N\u1D00");
wxString atomic_mass_unit(L"u");
wxString planck(L"h");
wxString gas(L"R");
wxString gravity_acceleration(L"g");
wxString golden_ratio(L"\u03D5");
}
namespace calc
{
std::map < wxString, std::function<long double(long double, long double)> > binary
{
{binary::add, [](long double a, long double b) { return a + b; }},
{binary::sub, [](long double a, long double b) { return a - b; }},
{binary::mul, [](long double a, long double b) { return a * b; }},
{binary::div, [](long double a, long double b) { return a / b; }},
{binary::pow, [](long double a, long double b) { return pow(a, b); }}
};
std::map < wxString, std::function<long double(long double)> > unary
{
{unary::sqrt, [](long double n) { return sqrt(n); }},
{unary::sin, [](long double n) { return sin(n * 3.14159265359 / 180); }}, //trasformazione da rad a gradi
{unary::cos, [](long double n) { return cos(n * 3.14159265359 / 180); }},
{unary::tan, [](long double n) { return tan(n * 3.14159265359 / 180); }},
{unary::arcsin, [](long double n) { return asin(n) * 180 / 3.14159265359; } }, //trasformazione da rad a gradi
{unary::arccos, [](long double n) { return acos(n) * 180 / 3.14159265359; } },
{unary::arctan, [](long double n) { return atan(n) * 180 / 3.14159265359; } }
};
std::map < wxString, long double > constant
{
{constant::pi, 3.14159265359},
{constant::light_speed, 299792458},
{constant::avogadro_number, 6.02214086 * pow(10, 23)},
{constant::atomic_mass_unit, 1.67 * pow(10, -27)},
{constant::planck, 6.626 * pow(10, -34)},
{constant::gas, 8.314},
{constant::gravity_acceleration, 9.80665},
{constant::golden_ratio, 1.6180339887}
};
}
inline bool isBinary(wxString needle)
{
return (calc::binary.count(needle));
}
inline bool isUnary(wxString needle)
{
return (calc::unary.count(needle));
}
inline bool isConstant(wxString needle)
{
return (calc::constant.count(needle));
}
编辑
我听从了一些建议并像这样修改了我的代码(仍然有问题):
ops.h
#pragma once
#include "wx/wx.h"
#include <cmath>
#include <map>
namespace binary {
extern const wxString add, sub, mul, div;
}
namespace unary {
extern const wxString sqrt, sin, cos, tan, arcsin, arccos, arctan;
}
namespace constant {
extern const wxString pi, light_speed, avogadro_number, atomic_mass_unit, planck, gas, gravity_acceleration, golden_ratio;
}
namespace calc
{
extern const std::map < wxString, std::function<long double(long double, long double)> > binary;
extern const std::map < wxString, std::function<long double(long double)> > unary;
extern const std::map < wxString, long double > constant;
}
bool isBinary(wxString needle);
bool isUnary(wxString needle);
bool isConstant(wxString needle);
ops.cpp
#include "ops.h"
namespace binary {
const wxString add(L"+"), sub(L"-");
const wxString mul(L"\u00D7"), div(L"\u00F7");
const wxString pow(L"^");
}
namespace unary {
const wxString sqrt(L"\u221A");
const wxString sin(L"sin"), cos(L"cos"), tan(L"tan");
const wxString arcsin(L"arcsin"), arccos(L"arccos"), arctan(L"tan");
}
namespace constant {
const wxString pi(L"\u03C0");
const wxString light_speed(L"c");
const wxString avogadro_number(L"N\u1D00");
const wxString atomic_mass_unit(L"u");
const wxString planck(L"h");
const wxString gas(L"R");
const wxString gravity_acceleration(L"g");
const wxString golden_ratio(L"\u03D5");
}
namespace calc
{
const std::map < wxString, std::function<long double(long double, long double)> > binary
{
{binary::add, [](long double a, long double b) { return a + b; }},
{binary::sub, [](long double a, long double b) { return a - b; }},
{binary::mul, [](long double a, long double b) { return a * b; }},
{binary::div, [](long double a, long double b) { return a / b; }},
{binary::pow, [](long double a, long double b) { return pow(a, b); }}
};
const std::map < wxString, std::function<long double(long double)> > unary
{
{unary::sqrt, [](long double n) { return sqrt(n); }},
{unary::sin, [](long double n) { return sin(n * 3.14159265359 / 180); }}, //trasformazione da rad a gradi
{unary::cos, [](long double n) { return cos(n * 3.14159265359 / 180); }},
{unary::tan, [](long double n) { return tan(n * 3.14159265359 / 180); }},
{unary::arcsin, [](long double n) { return asin(n) * 180 / 3.14159265359; } }, //trasformazione da rad a gradi
{unary::arccos, [](long double n) { return acos(n) * 180 / 3.14159265359; } },
{unary::arctan, [](long double n) { return atan(n) * 180 / 3.14159265359; } }
};
const std::map < wxString, long double > constant
{
{constant::pi, 3.14159265359},
{constant::light_speed, 299792458},
{constant::avogadro_number, 6.02214086 * pow(10, 23)},
{constant::atomic_mass_unit, 1.67 * pow(10, -27)},
{constant::planck, 6.626 * pow(10, -34)},
{constant::gas, 8.314},
{constant::gravity_acceleration, 9.80665},
{constant::golden_ratio, 1.6180339887}
};
}
bool isBinary(wxString needle)
{
return (calc::binary.count(needle));
}
bool isUnary(wxString needle)
{
return (calc::unary.count(needle));
}
bool isConstant(wxString needle)
{
return (calc::constant.count(needle));
}
编辑
我的另一个尝试(现在只有 19 个错误):
ops.h
#pragma once
#include "wx/wx.h"
#include <cmath>
#include <map>
namespace binary
{
extern const wxString add, sub, mul, div, pow;
}
namespace unary
{
extern const wxString sqrt, sin, cos, tan, arcsin, arccos, arctan;
}
namespace constant
{
extern const wxString pi, avogadro_number, planck, gas, atomic_mass_unit;
}
namespace calc
{
extern std::map < wxString, std::function<long double(long double, long double)> > binary;
extern std::map < wxString, std::function<long double(long double)> > unary;
extern std::map < wxString, long double > constant;
}
bool isBinary(wxString needle);
bool isUnary(wxString needle);
bool isConstant(wxString needle);
ops.cpp
#include "ops.h"
namespace binary
{
extern const wxString
add(L"+"),
sub(L"-"),
mul(L"\u00D7"),
div(L"\u00F7"),
pow(L"^");
}
namespace unary
{
extern const wxString
sqrt(L"\u221A"),
sin(L"sin"),
cos(L"cos"),
tan(L"tan"),
arcsin(L"arcsin"),
arccos(L"arccos"),
arctan(L"arctan");
}
namespace constant
{
extern const wxString
pi(L"\u03C0"),
avogadro_number(L"N\u2090"),
planck(L"h"),
gas(L"R"),
atomic_mass_unit(L"u");
}
namespace calc
{
extern std::map < wxString, std::function<long double(long double, long double)> > binary = {
{binary::add, [](long double a, long double b) { return a + b; }},
{binary::sub, [](long double a, long double b) { return a - b; }},
{binary::mul, [](long double a, long double b) { return a * b; }},
{binary::div, [](long double a, long double b) { return a / b; }},
{binary::pow, [](long double a, long double b) { return pow(a, b); }}
};
extern std::map < wxString, std::function<long double(long double)> > unary = {
{unary::sqrt, [](long double n) { return sqrt(n); }}
};
extern std::map < wxString, long double > constant = {
{constant::pi, 3.1415926535}
};
}
bool isBinary(wxString needle)
{
return (calc::binary.count(needle));
}
bool isUnary(wxString needle)
{
return (calc::unary.count(needle));
}
bool isConstant(wxString needle)
{
return (calc::constant.count(needle));
}
你试过了吗..
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
我只是个初学者,但我知道 pragma once != ifndef。
或者你的 .cpp 中可能有类似的东西。
问题是因为您在 .h
文件中有符号定义,所以您的每个符号都在每个编译单元中定义。即每个符号在A.cpp
中定义,然后又在B.cpp
、C.cpp
中定义,依此类推。最后你有几个同名的符号,这是不允许的。
解决方案是将所有这些定义移动到一个 .cpp
文件中,然后使用 extern
关键字在 .h
文件中声明它们。例如:extern wxString sqrt;
.
此外,由于您很可能不打算修改这些符号的值,因此所有符号都应该是 const wxString
而不仅仅是 wxString
.
我正在编写一个 C++ wxWidgets 计算器应用程序。我有这个头文件,我在其中声明我的应用程序支持的各种操作和常量。当我尝试编译时,出现 258 LNK2005 错误,例如:
Error LNK2005 "bool __cdecl isBinary(class wxString)" (?isBinary@@YA_NVwxString@@@Z) already defined in app.obj C:\Users\giorg\Desktop\Visual Studio\wxWidgetsTest\wxWidgetsTest\events.obj 1 ikeCalculator
Error LNK2005 "class wxString unary::tan" (?tan@unary@@3VwxString@@A) already defined in app.obj C:\Users\giorg\Desktop\Visual Studio\wxWidgetsTest\wxWidgetsTest\events.obj 1 ikeCalculator
此文件中的所有内容依此类推。每次在其他文件中引用这些对象之一时似乎都会出错。
#pragma once
#include "wx/wx.h"
#include <cmath>
#include <map>
namespace binary {
wxString add(L"+"), sub(L"-");
wxString mul(L"\u00D7"), div(L"\u00F7");
wxString pow(L"^");
}
namespace unary {
wxString sqrt(L"\u221A");
wxString sin(L"sin"), cos(L"cos"), tan(L"tan");
wxString arcsin(L"arcsin"), arccos(L"arccos"), arctan(L"tan");
}
namespace constant {
wxString pi(L"\u03C0");
wxString light_speed(L"c");
wxString avogadro_number(L"N\u1D00");
wxString atomic_mass_unit(L"u");
wxString planck(L"h");
wxString gas(L"R");
wxString gravity_acceleration(L"g");
wxString golden_ratio(L"\u03D5");
}
namespace calc
{
std::map < wxString, std::function<long double(long double, long double)> > binary
{
{binary::add, [](long double a, long double b) { return a + b; }},
{binary::sub, [](long double a, long double b) { return a - b; }},
{binary::mul, [](long double a, long double b) { return a * b; }},
{binary::div, [](long double a, long double b) { return a / b; }},
{binary::pow, [](long double a, long double b) { return pow(a, b); }}
};
std::map < wxString, std::function<long double(long double)> > unary
{
{unary::sqrt, [](long double n) { return sqrt(n); }},
{unary::sin, [](long double n) { return sin(n * 3.14159265359 / 180); }}, //trasformazione da rad a gradi
{unary::cos, [](long double n) { return cos(n * 3.14159265359 / 180); }},
{unary::tan, [](long double n) { return tan(n * 3.14159265359 / 180); }},
{unary::arcsin, [](long double n) { return asin(n) * 180 / 3.14159265359; } }, //trasformazione da rad a gradi
{unary::arccos, [](long double n) { return acos(n) * 180 / 3.14159265359; } },
{unary::arctan, [](long double n) { return atan(n) * 180 / 3.14159265359; } }
};
std::map < wxString, long double > constant
{
{constant::pi, 3.14159265359},
{constant::light_speed, 299792458},
{constant::avogadro_number, 6.02214086 * pow(10, 23)},
{constant::atomic_mass_unit, 1.67 * pow(10, -27)},
{constant::planck, 6.626 * pow(10, -34)},
{constant::gas, 8.314},
{constant::gravity_acceleration, 9.80665},
{constant::golden_ratio, 1.6180339887}
};
}
inline bool isBinary(wxString needle)
{
return (calc::binary.count(needle));
}
inline bool isUnary(wxString needle)
{
return (calc::unary.count(needle));
}
inline bool isConstant(wxString needle)
{
return (calc::constant.count(needle));
}
编辑
我听从了一些建议并像这样修改了我的代码(仍然有问题):
ops.h
#pragma once
#include "wx/wx.h"
#include <cmath>
#include <map>
namespace binary {
extern const wxString add, sub, mul, div;
}
namespace unary {
extern const wxString sqrt, sin, cos, tan, arcsin, arccos, arctan;
}
namespace constant {
extern const wxString pi, light_speed, avogadro_number, atomic_mass_unit, planck, gas, gravity_acceleration, golden_ratio;
}
namespace calc
{
extern const std::map < wxString, std::function<long double(long double, long double)> > binary;
extern const std::map < wxString, std::function<long double(long double)> > unary;
extern const std::map < wxString, long double > constant;
}
bool isBinary(wxString needle);
bool isUnary(wxString needle);
bool isConstant(wxString needle);
ops.cpp
#include "ops.h"
namespace binary {
const wxString add(L"+"), sub(L"-");
const wxString mul(L"\u00D7"), div(L"\u00F7");
const wxString pow(L"^");
}
namespace unary {
const wxString sqrt(L"\u221A");
const wxString sin(L"sin"), cos(L"cos"), tan(L"tan");
const wxString arcsin(L"arcsin"), arccos(L"arccos"), arctan(L"tan");
}
namespace constant {
const wxString pi(L"\u03C0");
const wxString light_speed(L"c");
const wxString avogadro_number(L"N\u1D00");
const wxString atomic_mass_unit(L"u");
const wxString planck(L"h");
const wxString gas(L"R");
const wxString gravity_acceleration(L"g");
const wxString golden_ratio(L"\u03D5");
}
namespace calc
{
const std::map < wxString, std::function<long double(long double, long double)> > binary
{
{binary::add, [](long double a, long double b) { return a + b; }},
{binary::sub, [](long double a, long double b) { return a - b; }},
{binary::mul, [](long double a, long double b) { return a * b; }},
{binary::div, [](long double a, long double b) { return a / b; }},
{binary::pow, [](long double a, long double b) { return pow(a, b); }}
};
const std::map < wxString, std::function<long double(long double)> > unary
{
{unary::sqrt, [](long double n) { return sqrt(n); }},
{unary::sin, [](long double n) { return sin(n * 3.14159265359 / 180); }}, //trasformazione da rad a gradi
{unary::cos, [](long double n) { return cos(n * 3.14159265359 / 180); }},
{unary::tan, [](long double n) { return tan(n * 3.14159265359 / 180); }},
{unary::arcsin, [](long double n) { return asin(n) * 180 / 3.14159265359; } }, //trasformazione da rad a gradi
{unary::arccos, [](long double n) { return acos(n) * 180 / 3.14159265359; } },
{unary::arctan, [](long double n) { return atan(n) * 180 / 3.14159265359; } }
};
const std::map < wxString, long double > constant
{
{constant::pi, 3.14159265359},
{constant::light_speed, 299792458},
{constant::avogadro_number, 6.02214086 * pow(10, 23)},
{constant::atomic_mass_unit, 1.67 * pow(10, -27)},
{constant::planck, 6.626 * pow(10, -34)},
{constant::gas, 8.314},
{constant::gravity_acceleration, 9.80665},
{constant::golden_ratio, 1.6180339887}
};
}
bool isBinary(wxString needle)
{
return (calc::binary.count(needle));
}
bool isUnary(wxString needle)
{
return (calc::unary.count(needle));
}
bool isConstant(wxString needle)
{
return (calc::constant.count(needle));
}
编辑
我的另一个尝试(现在只有 19 个错误):
ops.h
#pragma once
#include "wx/wx.h"
#include <cmath>
#include <map>
namespace binary
{
extern const wxString add, sub, mul, div, pow;
}
namespace unary
{
extern const wxString sqrt, sin, cos, tan, arcsin, arccos, arctan;
}
namespace constant
{
extern const wxString pi, avogadro_number, planck, gas, atomic_mass_unit;
}
namespace calc
{
extern std::map < wxString, std::function<long double(long double, long double)> > binary;
extern std::map < wxString, std::function<long double(long double)> > unary;
extern std::map < wxString, long double > constant;
}
bool isBinary(wxString needle);
bool isUnary(wxString needle);
bool isConstant(wxString needle);
ops.cpp
#include "ops.h"
namespace binary
{
extern const wxString
add(L"+"),
sub(L"-"),
mul(L"\u00D7"),
div(L"\u00F7"),
pow(L"^");
}
namespace unary
{
extern const wxString
sqrt(L"\u221A"),
sin(L"sin"),
cos(L"cos"),
tan(L"tan"),
arcsin(L"arcsin"),
arccos(L"arccos"),
arctan(L"arctan");
}
namespace constant
{
extern const wxString
pi(L"\u03C0"),
avogadro_number(L"N\u2090"),
planck(L"h"),
gas(L"R"),
atomic_mass_unit(L"u");
}
namespace calc
{
extern std::map < wxString, std::function<long double(long double, long double)> > binary = {
{binary::add, [](long double a, long double b) { return a + b; }},
{binary::sub, [](long double a, long double b) { return a - b; }},
{binary::mul, [](long double a, long double b) { return a * b; }},
{binary::div, [](long double a, long double b) { return a / b; }},
{binary::pow, [](long double a, long double b) { return pow(a, b); }}
};
extern std::map < wxString, std::function<long double(long double)> > unary = {
{unary::sqrt, [](long double n) { return sqrt(n); }}
};
extern std::map < wxString, long double > constant = {
{constant::pi, 3.1415926535}
};
}
bool isBinary(wxString needle)
{
return (calc::binary.count(needle));
}
bool isUnary(wxString needle)
{
return (calc::unary.count(needle));
}
bool isConstant(wxString needle)
{
return (calc::constant.count(needle));
}
你试过了吗..
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
我只是个初学者,但我知道 pragma once != ifndef。 或者你的 .cpp 中可能有类似的东西。
问题是因为您在 .h
文件中有符号定义,所以您的每个符号都在每个编译单元中定义。即每个符号在A.cpp
中定义,然后又在B.cpp
、C.cpp
中定义,依此类推。最后你有几个同名的符号,这是不允许的。
解决方案是将所有这些定义移动到一个 .cpp
文件中,然后使用 extern
关键字在 .h
文件中声明它们。例如:extern wxString sqrt;
.
此外,由于您很可能不打算修改这些符号的值,因此所有符号都应该是 const wxString
而不仅仅是 wxString
.