正确编码和调试的命名空间中未解析的函数

Unresolved Functions in Properly Coded and Debuged Namespace

提问人:Geowil 提问时间:7/20/2017 最后编辑:CommunityGeowil 更新时间:7/22/2017 访问量:95

问:

几天来,我一直在尝试解决 MSVS 15 中的概念验证测试项目的几个问题。我看到的问题是命名空间中有一些函数无法解析。

自动搜索 SO 列表中的热门问题都没有帮助我,因为我的代码没有他们遇到的问题。谷歌也未能提供任何有用的东西。只是与不属于我问题的其他 SO 问题相同的代码实现问题。

据我所知,命名空间代码是正确的,但链接器仍然找不到函数定义。命名空间中的所有函数都收到未解析的链接器错误。

util.h

#include <string>
#include <vector>
#include <map>
#include "logging.h"
#include <random>

using std::string;
using std::vector;
using std::map;
using std::pair;
using std::to_string;

namespace Util {
    //Utility Function Predefs
    map<string, float> fillMap(map<string, float>argMap);
    map<string, int> fillMap(map<string, int>argMap);

    void createBInfo(string errType, string fl, string lnNm, string dt, string tm, string errCode, string errMsg, string fPath);
    float calcPop(int pERand, int pSRand, int popRand1, int popRand2, int popRand3);
    int getDefenses(int rand, float eks);
    int getShields(int rand, float eks);
    int getIRand(int low, int high);
    float getFRand(float low, float high);
    int calcXP(int base, int level, float factor);

    //Utility Members
    extern map<string, float>::iterator itf1;
    extern map<string, int>::iterator iti1;
    extern map<string, float>rtnFMap;
    extern map<string, int>rtnIMap;

    extern int i1;
    extern int nOfDef;
    extern int nOfShd;

    //For Debug
    extern string file, bLocale, bTDate;
}

util.cpp

#include "util.h"
#include <math.h>
#include "consts.h"
#include "logging.h"

Logging l_u;
std::random_device rd;
std::mt19937 gen(rd());

namespace Util {
    //Name: fillMap
    //Description: Fill a map reference passed through with the contents of another map from dataSystem
    /*Arguments:
    *argMap1 - This map contains a map of settings loaded passed in from another function
    */
    map<string, float> fillMap(map<string, float>argMap1) {
        for (itf1 = argMap1.begin(); itf1 != argMap1.end(); itf1++) {
            rtnFMap.insert(pair<string, float>(itf1->first, itf1->second));
        }

        return rtnFMap;
    }

    //Name: fillMap
    //Description: Fill a map reference passed through with the contents of another map from dataSystem; int value override
    /*Arguments:
    *argMap1 - This map contains a map of settings loaded passed in from another function
    */
    map<string, int> fillMap(map<string, int>argMap1) {
        for (iti1 = argMap1.begin(); iti1 != argMap1.end(); iti1++) {
            rtnIMap.insert(pair<string, int>(iti1->first, iti1->second));
        }

        return rtnIMap;
    }


    void createBInfo(string errType, string fl, string lnNm, string dt, string tm, string errCode, string errMsg, string fPath) {
        file = fl;
        bLocale = "File: " + file + "  Line: " + lnNm;
        bTDate = dt + "  " + tm;

        l_u.createLReport(errType, errCode, errMsg, bLocale, bTDate, fPath);
    }

    int calcXP(int base, int level, float factor) {
        return trunc(base * (pow(level, factor)));
    }

    int getDefenses(int rand, float eks) {
        if ((eks > 0.0f) && (eks < 1.0f)) { //Type 0 Planet
            if ((rand >= 1) && (rand <= 35)) { nOfDef = 0; } //36% chance for 0 defenses        
            else if ((rand >= 36) && (rand <= 60)) { nOfDef = 1; } //25% chance for 1 defense
            else if ((rand >= 61) && (rand <= 78)) { nOfDef = 2; } //18% chance for 2 defenses
            else if ((rand >= 79) && (rand <= 87)) { nOfDef = 3; } //7% chance for 3 defenses
            else if ((rand >= 88) && (rand <= 94)) { nOfDef = 4; } //7% chance for 4 defenses
            else if ((rand >= 95) && (rand <= 98)) { nOfDef = 5; } //4% chance for 5 defenses
            else if (rand >= 99) { nOfDef = 6; } //2% Chance for 6 defenses
        }
        else if ((eks >= 1.0f) && (eks < 2.0f)) { //Type 1 Planet
            if ((rand >= 1) && (rand <= 28)) { nOfDef = 0; } //29% chance for 0 defenses        
            else if ((rand >= 29) && (rand <= 55)) { nOfDef = 1; } //28% chance for 1 defense
            else if ((rand >= 56) && (rand <= 71)) { nOfDef = 2; } //16% chance for 2 defenses
            else if ((rand >= 72) && (rand <= 82)) { nOfDef = 3; } //11% chance for 3 defenses
            else if ((rand >= 83) && (rand <= 90)) { nOfDef = 4; } //8% chance for 4 defenses
            else if ((rand >= 91) && (rand <= 96)) { nOfDef = 5; } //7% chance for 5 defenses
            else if (rand >= 97) { nOfDef = 6; } //4% Chance for 6 defenses
        }
        else if ((eks >= 2.0f) && (eks < 3.0f)) { //Type 2 Planet
            if ((rand >= 1) && (rand <= 28)) { nOfDef = 0; } //29% chance for 0 defenses        
            else if ((rand >= 29) && (rand <= 56)) { nOfDef = 1; } //28% chance for 1 defense
            else if ((rand >= 57) && (rand <= 70)) { nOfDef = 2; } //14% chance for 2 defenses
            else if ((rand >= 71) && (rand <= 82)) { nOfDef = 3; } //12% chance for 3 defenses
            else if ((rand >= 83) && (rand <= 91)) { nOfDef = 4; } //9% chance for 4 defenses
            else if ((rand >= 92) && (rand <= 96)) { nOfDef = 5; } //5% chance for 5 defenses
            else if (rand >= 97) { nOfDef = 6; } //4% Chance for 6 defenses
        }
        else if ((eks >= 3.0f) && (eks < 4.0f)) { //Type 3 Planet
            if ((rand >= 1) && (rand <= 20)) { nOfDef = 0; } //21% chance for 0 defenses        
            else if ((rand >= 21) && (rand <= 46)) { nOfDef = 1; } //26% chance for 1 defense
            else if ((rand >= 47) && (rand <= 68)) { nOfDef = 2; } //19% chance for 2 defenses
            else if ((rand >= 69) && (rand <= 80)) { nOfDef = 3; } //13% chance for 3 defenses
            else if ((rand >= 81) && (rand <= 89)) { nOfDef = 4; } //9% chance for 4 defenses
            else if ((rand >= 90) && (rand <= 95)) { nOfDef = 5; } //6% chance for 5 defenses
            else if (rand >= 96) { nOfDef = 6; } //3% Chance for 6 defenses
        }
        else if ((eks >= 4.0f) && (eks < 5.0f)) { //Type 4 Planet
            if (rand >= 1 && rand <= 18) { nOfDef = 0; } //19% chance for 0 defenses        
            else if (rand >= 19 && rand <= 35) { nOfDef = 1; } //15% chance for 1 defense
            else if (rand >= 36 && rand <= 55) { nOfDef = 2; } //20% chance for 2 defenses
            else if (rand >= 56 && rand <= 68) { nOfDef = 3; } //13% chance for 3 defenses
            else if (rand >= 69 && rand <= 80) { nOfDef = 4; } //12% chance for 4 defenses
            else if (rand >= 81 && rand <= 89) { nOfDef = 5; } //9% chance for 5 defenses
            else if (rand >= 90 && rand <= 95) { nOfDef = 6; } //6% Chance for 6 defenses
            else if (rand >= 96) { nOfDef = 7; } //5% chance for 7 defenses
        }
        else if (eks >= 5.0f) { //Type 5 Planet
            if (rand >= 1 && rand <= 12) { nOfDef = 0; } //13% chance for 0 defenses        
            else if (rand >= 13 && rand <= 28) { nOfDef = 1; } //16% chance for 1 defense
            else if (rand >= 29 && rand <= 48) { nOfDef = 2; } //20% chance for 2 defenses
            else if (rand >= 49 && rand <= 62) { nOfDef = 3; } //14% chance for 3 defenses
            else if (rand >= 63 && rand <= 74) { nOfDef = 4; } //12% chance for 4 defenses
            else if (rand >= 75 && rand <= 85) { nOfDef = 5; } //11% chance for 5 defenses
            else if (rand >= 86 && rand <= 92) { nOfDef = 6; } //9% Chance for 6 defenses
            else if (rand >= 93 && rand <= 97) { nOfDef = 7; } //5% Chance for 7 defenses
            else if (rand >= 98) { nOfDef = 8; } //3% chance for 8 defenses
        }
        
        return nOfDef;
    }

    int getShields(int rand, float eks) {
        if ((eks > 0.0f) && (eks < 1.0f)) { //Type 0 Planet
            if ((rand >= 1) && (rand <= 60)) { nOfShd = 0; } //61% chance for 0 shields
            else if ((rand >= 61) && (rand <= 86)) { nOfShd = 1; } //26% chance for 1 shields
            else if (rand >= 86) { nOfShd = 2; } //17% chance for 2 shields
        }
        else if ((eks >= 1.0f) && (eks < 2.0f)) { //Type 1 Planet
            if ((rand >= 1) && (rand <= 52)) { nOfShd = 0; } //53% chance for 0 shields
            else if ((rand >= 53) && (rand <= 84)) { nOfShd = 1; } //22% chance for 1 shields
            else if (rand >= 85) { nOfShd = 2; } //15% chance for 2 shields
        }
        else if ((eks >= 2.0f) && (eks < 3.0f)) { //Type 2 Planet
            if ((rand >= 1) && (rand <= 35)) { nOfShd = 0; } //36% chance for 0 shields
            else if ((rand >= 36) && (rand <= 68)) { nOfShd = 1; } //33% chance for 1 shields
            else if ((rand >= 68) && (rand <= 87)) { nOfShd = 2; } //18% chance for 2 shields
            else if (rand >= 88) { nOfShd = 3; } //13% chance for 3 shields
        }
        else if ((eks >= 3.0f) && (eks < 4.0f)) { //Type 3 Planet
            if ((rand >= 1) && (rand <= 27)) { nOfShd = 0; } //28% chance for 0 shields
            else if ((rand >= 28) && (rand <= 64)) { nOfShd = 1; } //27% chance for 1 shields
            else if ((rand >= 65) && (rand <= 84)) { nOfShd = 2; } //21% chance for 2 shields
            else if (rand >= 85) { nOfShd = 3; } //16% chance for 3 shields
        }
        else if ((eks >= 4.0f) && (eks < 5.0f)) { //Type 4 Planet
            if ((rand >= 1) && (rand <= 20)) { nOfShd = 0; } //21% chance for 0 shields
            else if ((rand >= 21) && (rand <= 48)) { nOfShd = 1; } //28% chance for 1 shields
            else if ((rand >= 49) && (rand <= 74)) { nOfShd = 2; } //26% chance for 2 shields
            else if ((rand >= 75) && (rand <= 88)) { nOfShd = 3; } //14% chance for 3 shields
            else if (rand >= 89) { nOfShd = 4; } //12% chance for 4 shields
        }
        else if (eks >= 5.0f) { //Type 5 Planet
            if ((rand >= 1) && (rand <= 18)) { nOfShd = 0; } //19% chance for 0 shields
            else if ((rand >= 19) && (rand <= 36)) { nOfShd = 1; } //18% chance for 1 shields
            else if ((rand >= 37) && (rand <= 65)) { nOfShd = 2; } //29% chance for 2 shields
            else if ((rand >= 66) && (rand <= 84)) { nOfShd = 3; } //19% chance for 3 shields
            else if (rand >= 85) { nOfShd = 4; } //16% chance for 4 shields
        }

        return nOfShd;
    }

    float calcPop(int pERand, int pSRand, int popRand1, int popRand2, int popRand3) {
        return ((((((8000 * popRand1) * popRand2) * pERand) * pSRand) * popRand3) / 6);
    }

    int getIRand(int low, int high) {
        return std::uniform_int_distribution<>{low, high}(gen);
    }

    float getFRand(float low, float high) {
        return std::uniform_real_distribution<float> {low, high}(gen);
    }
}

导致错误的命名空间函数调用的摘录示例:

#include <iostream>
#include <stdlib.h>
#include "planet.h"
#include <Windows.h>
#include <sstream>
#include <cmath>
#include "util.h"
#include "consts.h"

...

void Planet::createBelts() {
    beltRand = Util::getIRand(0, 10);

    if (beltRand != 0) {
        for (i = 1; i <= beltRand; i++) {
            ramount = Util::getIRand(3, 15); //External value tag: int range
            size = ((ramount * Util::getFRand(1000.0f, 50000.00f) * 46) / 2); //External value tag: float range
            name = plName + " Asteroid Belt " + rNumerals[i - 1];

            addBelt(name, size, ramount, false);
        }
    }
}

...

更新:

以下是我看到的一些链接器错误。

未解析的外部符号“浮点__cdecl Util::calcPop(int,int,int,int,int)“ (?calcPop@Util@@YAMHHHHH@Z) 在函数“public: void __thiscall中引用 planetarySystem::generatePlanets(void)” (?generatePlanets@planetarySystem@@QAEXXZ)

未解析的外部符号 “float __cdecl Util::getFRand(float,float)” (?getFRand@Util@@YAMMM@Z)

未解析的外部符号“float __cdecl Util::getFRand(float,float)” (?getFRand@Util@@YAMMM@Z) 未解析的外部符号“浮点__cdecl Util::getFRand(浮点,浮点)“(?getFRand@Util@@YAMMM@Z)

解决 外部符号 “int __cdecl Util::getDefenses(int,float)” (?getDefenses@Util@@YAHHM@Z)

C++ 链接器 循环依赖项 未解析外部

评论

0赞 Scheff's Cat 7/20/2017
链接 exe 或 dll 时会出现链接错误。这发生在编译完成后(对于这个项目),尽管我(相信我)有时会看到编译错误,然后导致链接错误。输出日志提供所有检测到的错误的完整列表。(这是关于“未解决的外部符号错误可能会消除任何其他错误”的说法,但我可能让你理解错了。
2赞 user4581301 7/20/2017
可能的原因太多了。代码太多了。建议将重点放在一个错误上,并将代码简化为重现该错误的最小可重现示例
0赞 molbdnilo 7/20/2017
使用正常方法:解决第一个错误,然后继续下一个错误,直到所有错误都消失。(如果不看,我猜问题出在变量上,而不是函数上。
0赞 user0042 7/20/2017
什么是未定义的引用/未解析的外部符号错误以及如何修复它?
0赞 user0042 7/20/2017
其他重复/相关:stackoverflow.com/questions/625799/...

答:

0赞 Geowil 7/21/2017 #1

所以,四天后,我终于找到了与命名空间问题有关的问题。项目所在的解决方案文件是在 MSVS 2012 中生成的,并在一段时间前转换为 MSVS 2015。我不知道为什么这很重要,但是当我在 2015 年创建一个全新的项目并将代码文件扔进去时,我的命名空间未解决的链接器错误得到了修复。