0

这个网站上这个问题的每个答案(从我所见,很多)都在我的案例中得到了解决,但我仍然处于僵局。我正在使用遗留代码,不得不通过设置正确连接的开发环境来破解我的方式。使用 VS 2012,我有一个包含 22 个项目的解决方案,它们之间有一个蜘蛛网的依赖关系。第一个项目 phtranscript 依赖于另一个项目 hunspell 的代码,而第三个项目 SpeechRecognizer 又需要 phtranscript 的代码。以下是相关文件和编译器/链接器输出:

在项目 phtranscript 中:

phTranscript.h:

#ifndef _phTranscript_h__
#define _phTranscript_h__

#include <vector>
#include <string>
#include <map>
#include "config.h"
#include "character.h"
...
class hunspellMorph{
public:
    static hunspellMorph *instance();
protected:
    hunspellMorph();

private:
    hunspellMorph(const hunspellMorph &);
    hunspellMorph& operator=(const hunspellMorph &);

public:
    ~hunspellMorph();

    void Morph(const std::string &in,std::vector<std::string> &out);

private:
    class impl;
    impl *pImpl_;
};


#endif

hunspellMorph.cpp:

#include "phTranscript.h"
#include "hunspell.hxx"
#include <treeNode.h>

#include <string.h>

class hunspellMorph::impl{
private:
    Hunspell hs;

public:
    impl();

    void Morph(const std::string &in,std::vector<std::string> &out);

};

void hunspellMorph::impl::Morph(const std::string &in,std::vector<std::string> &out){
    char **slst;
    int re = hs.analyze(&slst,in.c_str());
    ...
    freelist(&slst,re);
}

hunspellMorph::hunspellMorph(){
    pImpl_ = new impl();
}

hunspellMorph::~hunspellMorph(){
    delete pImpl_;
}

....

在项目 hunspell 中:

hunspell.hxx:

#include "affixmgr.hxx"
#include "suggestmgr.hxx"
#include "csutil.hxx"
#include "langnum.hxx"

#define  SPELL_COMPOUND  (1 << 0)
#define  SPELL_FORBIDDEN (1 << 1)
#define  SPELL_ALLCAP    (1 << 2)
#define  SPELL_NOCAP     (1 << 3)
#define  SPELL_INITCAP   (1 << 4)

#define MAXDIC 20
#define MAXSUGGESTION 15
#define MAXSHARPS 5

#ifndef _HUNSPELL_HXX_
#define _HUNSPELL_HXX_

class Hunspell
{
    ...
public:
    Hunspell(const char * affpath, const char * dpath, const char * key = NULL);
    ~Hunspell();

    int analyze(char ***slst,const char *word,int d=0);
    ...
};
#endif

csutil.hxx:

#ifndef __CSUTILHXX__
#define __CSUTILHXX__

// First some base level utility routines

#define NOCAP   0
#define INITCAP 1
#define ALLCAP  2
#define HUHCAP  3
#define HUHINITCAP  4

#define MORPH_STEM        "st:"
#define MORPH_ALLOMORPH   "al:"
#define MORPH_POS         "po:"
#define MORPH_DERI_PFX    "dp:"
#define MORPH_INFL_PFX    "ip:"
#define MORPH_TERM_PFX    "tp:"
#define MORPH_DERI_SFX    "ds:"
#define MORPH_INFL_SFX    "is:"
#define MORPH_TERM_SFX    "ts:"
#define MORPH_SURF_PFX    "sp:"
#define MORPH_FREQ        "fr:"
#define MORPH_PHON        "ph:"
#define MORPH_HYPH        "hy:"
#define MORPH_PART        "pa:"
#define MORPH_HENTRY      "_H:"
#define MORPH_TAG_LEN     strlen(MORPH_STEM)

#define MSEP_FLD ' '
#define MSEP_REC '\n'
#define MSEP_ALT '\v'

// default flags
#define DEFAULTFLAGS   65510
#define FORBIDDENWORD  65510
#define ONLYUPCASEFLAG 65511

typedef struct {
    unsigned char l;
    unsigned char h;
} w_char;

#define w_char_eq(a,b) (((a).l == (b).l) && ((a).h == (b).h))

...
// free character array list
void freelist(char *** list, int n);
#endif

hunspell.cxx:

#include "license.hunspell"
#include "license.myspell"

#ifndef MOZILLA_CLIENT
#include <cstdlib>
#include <cstring>
#include <cstdio>
#else
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#endif

#include "hunspell.hxx"
#include "./config.h"
#include "./treeNode.h"
#include "cache.h"

#include <string>
#include <vector>

#ifndef MOZILLA_CLIENT
#ifndef W32
using namespace std;
#endif
#endif

Hunspell::Hunspell(const char * affpath, const char * dpath, const char * key)
{
    ...
}

Hunspell::~Hunspell()
{
    ...
}

int Hunspell::analyze(char ***slst,const char *word,int d){
    ...
}

csutil.cxx:

#include "license.hunspell"
#include "license.myspell"

#ifndef MOZILLA_CLIENT
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cctype>
#else
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#endif

#include "csutil.hxx"
#include "atypes.hxx"
#include "langnum.hxx"

#ifdef OPENOFFICEORG
#  include <unicode/uchar.h>
#else
#  ifndef MOZILLA_CLIENT
#    include "utf_info.cxx"
#    define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info)))
#  endif
#endif

#ifdef MOZILLA_CLIENT
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsICaseConversion.h"
#include "nsICharsetConverterManager.h"
#include "nsUnicharUtilCIID.h"
#include "nsUnicharUtils.h"

static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
#endif

#ifdef MOZILLA_CLIENT
#ifdef __SUNPRO_CC // for SunONE Studio compiler
using namespace std;
#endif
#else
#ifndef W32
using namespace std;
#endif
#endif

...

void freelist(char *** list, int n) {
    if (list && (n > 0)) {
        for (int i = 0; i < n; i++) if ((*list)[i]) free((*list)[i]);
        free(*list);
        *list = NULL;
    }
}

这是不同项目之间干净构建的输出:

6>------ Build started: Project: hunspell, Configuration: Debug Win32 ------
...
6>  hunspell.vcxproj -> C:\temp\speech\divided_rm_speech_proj\Debug\hunspell.exe
...
10>------ Build started: Project: phtranscript, Configuration: Debug Win32 ------
...
10>  phtranscript.vcxproj -> C:\temp\speech\divided_rm_speech_proj\Debug\phtranscript.exe
...
19>------ Build started: Project: speechRecognizer, Configuration: Debug Win32 ------
...
19>  Generating Code...
19>hunspellMorph.obj : error LNK2019: unresolved external symbol "void __cdecl freelist(char * * *,int)" (?freelist@@YAXPAPAPADH@Z) referenced in function "public: void __thiscall hunspellMorph::impl::Morph(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &)" (?Morph@impl@hunspellMorph@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@@Z)
19>hunspellMorph.obj : error LNK2019: unresolved external symbol "public: __thiscall Hunspell::Hunspell(char const *,char const *,char const *)" (??0Hunspell@@QAE@PBD00@Z) referenced in function "public: __thiscall hunspellMorph::impl::impl(void)" (??0impl@hunspellMorph@@QAE@XZ)
19>hunspellMorph.obj : error LNK2019: unresolved external symbol "public: __thiscall Hunspell::~Hunspell(void)" (??1Hunspell@@QAE@XZ) referenced in function "public: __thiscall hunspellMorph::impl::~impl(void)" (??1impl@hunspellMorph@@QAE@XZ)
19>hunspellMorph.obj : error LNK2019: unresolved external symbol "public: int __thiscall Hunspell::analyze(char * * *,char const *,int)" (?analyze@Hunspell@@QAEHPAPAPADPBDH@Z) referenced in function "public: void __thiscall hunspellMorph::impl::Morph(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &)" (?Morph@impl@hunspellMorph@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@@Z)
19>C:\temp\speech\divided_rm_speech_proj\Debug\speechRecognizer.exe : fatal error LNK1120: 4 unresolved externals

请记住,有很多代码被删除,所以如果缺少重要的东西,请告诉我,我会更新这个描述。

在Visual Studio 2012的环境设置中,phtranscript的项目属性在common属性下建立了一个hunspell引用,include目录字段包括hunspell包含目录,库目录字段包括hunspell库输出文件夹(这个都在VC++目录下), C/C++ 附加的包含目录也列出了 hunspell 包含目录。我单独留下了 Linker->Input additional libraries 字段,因为当我同时指定它和 VC++ 目录时出现“已声明符号”链接器错误。在项目依赖项下,我检查了 hunspell 并确保它在构建顺序中位于 phtranscript 之前。最后,我手动将现有的 hunspell 库(在它们编译后)添加到 phtranscript 项目中。在语音识别器项目中,我

代码几乎是 imo 的噩梦。解决此问题所需的最少更改量是多少?最好只是通过在 IDE 端更改/添加一些东西而不是代码更改(尽管这些是不可避免的)。

更新:

所有项目都被指定为项目属性下的应用程序。将它们更改为静态库(除了要执行的 1 个项目之外的所有项目)后,链接错误变为:

21>speechRecognizer.lib(hunspellMorph.obj) : error LNK2019: unresolved external symbol "void __cdecl freelist(char * * *,int)" (?freelist@@YAXPAPAPADH@Z) referenced in function "public: void __thiscall hunspellMorph::impl::Morph(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &)" (?Morph@impl@hunspellMorph@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@@Z)
21>speechRecognizer.lib(hunspellMorph.obj) : error LNK2019: unresolved external symbol "public: __thiscall Hunspell::Hunspell(char const *,char const *,char const *)" (??0Hunspell@@QAE@PBD00@Z) referenced in function "public: __thiscall hunspellMorph::impl::impl(void)" (??0impl@hunspellMorph@@QAE@XZ)
21>speechRecognizer.lib(hunspellMorph.obj) : error LNK2019: unresolved external symbol "public: __thiscall Hunspell::~Hunspell(void)" (??1Hunspell@@QAE@XZ) referenced in function "public: __thiscall hunspellMorph::impl::~impl(void)" (??1impl@hunspellMorph@@QAE@XZ)
21>speechRecognizer.lib(hunspellMorph.obj) : error LNK2019: unresolved external symbol "public: int __thiscall Hunspell::analyze(char * * *,char const *,int)" (?analyze@Hunspell@@QAEHPAPAPADPBDH@Z) referenced in function "public: void __thiscall hunspellMorph::impl::Morph(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &)" (?Morph@impl@hunspellMorph@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@4@@Z)
21>C:\temp\speech\divided_rm_speech_proj\Debug\interface11.exe : fatal error LNK1120: 8 unresolved externals

这些链接错误等到最后编译应用程序时才会出现,而不是在将语音识别器编译为应用程序时出现。还有其他未解决的联系,但它们似乎与这个问题无关(尽管相关)。

4

1 回答 1

0

您的输出告诉我,这两个项目都编译为 *.exe 文件。在这种情况下,我不知道您希望“phtranscript”如何使用作为“hunspell”一部分的模块。

如果您创建此类依赖项,则 hunspell 应该是静态(或动态)库,phtranscript 链接到该库。我相信您确实正确设置了所有依赖项,但是 VS 没有任何东西可以链接在一起,这就是链接器对您如此生气的原因 - 它不能使用 *.exe 作为依赖项。

简单的解决方案:将“hunspell”类型更改为“静态库(.lib)”或“动态库(.dll)”并设置“phtranscript”以将其用作输入库。

于 2013-12-17T01:33:40.500 回答