链接时对CryptoPP :: AlignedAllocate的未定义引用

时间:2015-06-23 12:14:07

标签: c++ mingw crypto++

我在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);
    }


建议赞赏!

3 个答案:

答案 0 :(得分:5)

AlignedAllocate位于misc.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_ENABLEDconfig.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 ...

然后,你来了一个闪亮的新英特尔或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的纯软件实现。它的表现不尽如人意。

答案 1 :(得分:1)

我和MSYS2的MinGW64版本一样经历过同样的事情

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

编辑:实际上,从来没有找到我的第一个答案。 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

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

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

问题中的示例编译并使用以这种方式编译的库完美地运行,使用与Qt捆绑的MinGW 4.9.2和独立的MingGW-w64 5.2.0进行测试。

基本思想来自here,我只是改进了它。

答案 2 :(得分:0)

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

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

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

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

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

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

我的代码没有任何错误

如果你愿意,可以在窗口中测试它,并在windows中的qt创建器中添加两个top语句。