【问题标题】:Undefined reference to CryptoPP::AlignedAllocate when linking链接时对 CryptoPP::AlignedAllocate 的未定义引用
【发布时间】:2015-09-09 05:41:36
【问题描述】:

我在 Windows 中编译 cryptopp 项目时遇到以下错误。

C:\Users\Sajith\AppData\Local\Temp\ccxq8O8x.o:aescbc.cpp:(.text$_ZN8CryptoPP20AllocatorWithCleanupIhLb1EE8allocateEjPKv[
__ZN8CryptoPP20AllocatorWithCleanupIhLb1EE8allocateEjPKv]+0x2e): undefined reference to `CryptoPP::AlignedAllocate(unsig
ned int)'
C:\Users\Sajith\AppData\Local\Temp\ccxq8O8x.o:aescbc.cpp:(.text$_ZN8CryptoPP20AllocatorWithCleanupIhLb1EE10deallocateEPv
j[__ZN8CryptoPP20AllocatorWithCleanupIhLb1EE10deallocateEPvj]+0x28): undefined reference to `CryptoPP::AlignedDeallocate
(void*)'
collect2.exe: error: ld returned 1 exit status


下面是我的编译命令:

mingw32-g++.exe -o .\aestest2.exe .\aescbc.cpp   -I "C:\cryptopp\Include" -L "C:\cryptopp\Lib" -lcryptopp


我的 libcryptopp.a 位于 C:\cryptopp\Lib
我试图找出AlignedDeallocate 的声明位置,但找不到。

引发此错误的程序部分如下:

try
    {
        cout << "plain text: " << plain << endl;

        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, sizeof(key), iv);

        // The StreamTransformationFilter removes
        //  padding as required.
        StringSource s(plain, true, 
            new StreamTransformationFilter(e,
                new StringSink(cipher)
            ) // StreamTransformationFilter
        ); // StringSource

#if 0
        StreamTransformationFilter filter(e);
        filter.Put((const byte*)plain.data(), plain.size());
        filter.MessageEnd();

        const size_t ret = filter.MaxRetrievable();
        cipher.resize(ret);
        filter.Get((byte*)cipher.data(), cipher.size());
#endif
    }
    catch(const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
        exit(1);
    }


建议赞赏!

【问题讨论】:

  • 不管怎样,上面的示例应该可以工作。代码看起来不错,编译它的命令格式也不错。

标签: c++ mingw crypto++


【解决方案1】:

AlignedAllocatemisc.h

$ grep -I AlignedAllocate *
misc.cpp:void * AlignedAllocate(size_t size)
misc.h:CRYPTOPP_DLL void * CRYPTOPP_API AlignedAllocate(size_t size);
secblock.h:                     return (pointer)AlignedAllocate(n*sizeof(T));

还有:

$ grep -R AlignedDeallocate *
misc.cpp:void AlignedDeallocate(void *p)
misc.h:CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *p);
secblock.h:                     return AlignedDeallocate(p);

但是,它们受到以下保护:

#if CRYPTOPP_BOOL_ALIGN16_ENABLED
CRYPTOPP_DLL void * CRYPTOPP_API AlignedAllocate(size_t size);
CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *p);
#endif

CRYPTOPP_BOOL_ALIGN16_ENABLED 设置在config.h:

#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)
    #define CRYPTOPP_BOOL_ALIGN16_ENABLED 1
#else
    #define CRYPTOPP_BOOL_ALIGN16_ENABLED 0
#endif

在 Crypto++ 在内部做出选择之后,您可以考虑将以下内容添加到 config.h

#undef CRYPTOPP_BOOL_ALIGN16_ENABLED
#define CRYPTOPP_BOOL_ALIGN16_ENABLED 1

然后,重建库和程序。


可能发生的其他事情是:MinGW 正在禁用 MMX/SSE/SSE2 的机器上构建库。或者他们正在使用g++ -mno-sse -mno-sse2 ...

然后,您获得了全新的 Intel 或 AMD,并且基于 g++ 启用的功能和 config.h 中的定义,您的程序需要 AlignedAllocateAlignedDeallocate,因为您的配置包括 MMX/SSE/SSE2 ...

Crypto++ wiki 上的 config.h | Recommendations 讨论了这种情况。这就是为什么我们告诉发行版在config.h 中启用和禁用某些东西,而不是从命令行。修改config.h 可确保发行版和用户程序大多使用相同的设置。

如果是这种情况,那么你可以试试:

export CXXFLAGS="-DNDEBUG -g2 -O2 -mno-sse -mno-sse2"
mingw32-g++.exe $CXXFLAGS -o .\aestest2.exe .\aescbc.cpp \
  -I "C:\cryptopp\Include" -L "C:\cryptopp\Lib" -lcryptopp

有大量基于 MMX/SSE/SSE2 的级联定义;请参阅维基上的config.h | Assembly Defines。因为 MMX/SSE/SSE2 被禁用,您将获得 AES 的纯软件实现。它不会表现得那么好。

【讨论】:

  • 只是出于好奇,在发布此问题之前,我已经打印了CRYPTOPP_BOOL_ALIGN16_ENABLED 的值,它显示为 1。
  • @sjsam - 在misc.cpp 中定义;请参阅上面的 grep。
  • @sjsam - 你能验证符号是从库中导出的吗? CRYPTOPP_DLL(实际上是标记导出内容的方式)、Windows 和 Linux on Windows 工具之间可能存在不良交互。
  • 你好,杰夫!用 mingw 编译 CryptoPP 让我很伤心。当我接近最后期限时,我决定将我的设计平台从 CodeBlocks 切换到 VisualStudio,因为我也遇到了 mysql 等其他库的问题。我用 VisualStudio 重新编译了 CryptoPP,它就像一个魅力。我无法缩小问题的范围,但我坚信问题就是您所指出的。当我回到 mingw 时,我会回复你。 :)
  • @sjsam - if 你是在 CodeBlocks 下构建库,那么我认为你需要定义 CRYPTOPP_EXPORTS。当您使用该库时,您忽略/不使用CRYPTOPP_EXPORTS用 mingw 编译 Crypto++ 给我的只是悲伤...... - 是的,我像瘟疫一样避开 Cygwin、MinGW 和 WINE。我使用本地平台的工具(在罗马时,像罗马人那样做......)。
【解决方案2】:

我在使用 MSYS2 的 MinGW64 版本时也遇到过同样的事情

解决方案是在-lcryptopp 之前添加-static。希望这对你有用!

编辑:实际上,不要介意我的第一个答案。 MSYS2 的存储库中可能有一个损坏的共享库版本,但我猜你自己编译了它。

我将提供一种如何使用 MinGW 编译 Crypto++ 的方法。您需要 Qt 的 qmake 来生成 Makefile,而不是使用包含的。

首先,打开 GNUMakefile 并查找 TESTOBJS,从 5.6.2 开始,它是 bench.o bench2.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o。您需要删除具有相同名称的 .cpps,这样您就不会构建一个臃肿的库。

然后打开 cmd.exe(PATH 包含 MinGW 的 /bin 和 qmake.exe 所在的目录),导航到包含源的目录并使用这些:

erase /f GNUmakefile
qmake -project

它将使用当前文件夹的名称和扩展名“.pro”创建一个文件。用文本编辑器打开,修改

TEMPLATE = app
TARGET = cryptopp562
INCLUDEPATH += .

TEMPLATE = lib
TARGET = cryptopp
INCLUDEPATH += .
CONFIG -= qt
CONFIG += static
LIBS += -lws2_32
QMAKE_CXXFLAGS_RELEASE += -DNDEBUG

fipstest.cpp 中的每个 OutputDebugString 替换为 OutputDebugStringA

现在您可以输入qmake 来生成新的Makefile 并使用mingw32-make。会有大量警告,主要是关于未使用的参数。然而,没有什么严重到可以取消编译的。 libcryptopp.a 将在 ./release/ 中。

问题中的示例可以使用这种方式编译的库进行编译并且工作得非常好,使用与 Qt 捆绑的 MinGW 4.9.2 和独立的 MingGW-w64 5.2.0 进行测试。

基本思路来自here,我只是改进了一下。

【讨论】:

  • 这其实是无关的。 jww的回答是正确的。
  • @AlexanderShishenko,好吧,jww 的回答说要定义 CRYPTOPP_BOOL_ALIGN16_ENABLED 并且 OP 回答说他已经检查过它是否已定义。除非我错过了什么?
  • @AlexanderShishenko,但你是对的。并非完全不相关,因为到目前为止,MSYS2 实际上在其存储库中确实有一个损坏的库共享版本,但是 OP 使用 MSYS2 来自存储库的库的可能性非常小.我已经编辑了答案,而是解释了如何使用 MinGW 编译 Crypto++ 并避免链接问题。
  • @Zireael - 很高兴在这里见到你。再次感谢Issue 46 的帮助。我看到你提到了 Qtqmake.exe。您一定会想访问 Crypto++ wiki 上的 Visual Studio。它提供了预转换的 Visual Studio 2010 项目文件 (vs2010.zip);和预转换的 Visual Studio 2010 项目文件,使用与 MFC、Qt 等兼容的动态链接 (vs2010-dynamic.zip)。
  • “首先,打开 GNUMakefile... 你需要删除同名的 .cpps,这样你就不会构建一个臃肿的库” - 你现在可以做一个make sources 并获取您应该为库和测试程序构建的文件列表。现在只需复制/粘贴即可轻松获取您的文件列表。
【解决方案3】:

如果您在程序中使用Crypto++,请注意:

此解决方案适用于 linux,如果您执行以下命令,您的问题 100%解决!!!

如果您想链接您的 .so 文件并最终编译您的程序,首先您必须在 ubuntu 或其他发行版(debian base linux)中安装 Synaptic 工具中的所有 Crypto++ 库。

之后,您最常在 qt 创建器中将-lcryptopp 或/和-lcrypto++ 添加到您的.pro 文件中,如下所示:

LIBS += -lcryptopp
LIBS += -lcrypto++

我有这个问题,但我的问题解决了......

我的代码没有任何错误

如果你愿意,可以在 window 中进行测试,然后在 windows 中的 qt creator 中添加两个 top 语句。

【讨论】:

    猜你喜欢
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 2020-11-11
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多