0

すべてのテストをGoogleTestからVisualStudio2012の単体テストフレームワークに移植しました。(長い話。Googleの主張は優れていますが、MicrosoftはDev11ユニットテストエクスプローラーをすぐに使用できるため、コードカバレッジを非常に簡単に取得できます...)

Win32リソースから改行区切りのテキストファイルを読み取り、そのリソースをすばやく検索できる次のクラスを除いて、すべてが正常に移植されました。

#include "pch.hpp"
#include "resource.h"
#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <windows.h>
#include "Win32Exception.hpp"
#include "Whitelist.hpp"

using Instalog::SystemFacades::Win32Exception;

namespace Instalog {

    Whitelist::Whitelist( __int32 whitelistId , std::vector<std::pair<std::wstring, std::wstring>> const& replacements )
    {
        using namespace std::placeholders;

        HRSRC resourceHandle = ::FindResource(0, MAKEINTRESOURCEW(whitelistId), L"WHITELIST");
        if (resourceHandle == 0)
        {
            Win32Exception::ThrowFromLastError();
        }
        HGLOBAL resourceGlobal = ::LoadResource(0, resourceHandle);
        if (resourceGlobal == 0)
        {
            Win32Exception::ThrowFromLastError();
        }
        void * resourceData = ::LockResource(resourceGlobal);
        if (resourceData == 0)
        {
            Win32Exception::ThrowFromLastError();
        }
        wchar_t const* resourceDataCasted = static_cast<wchar_t const*>(resourceData);
        DWORD resourceLen = ::SizeofResource(0, resourceHandle);
        auto sourceRange = boost::make_iterator_range(resourceDataCasted, resourceDataCasted + (resourceLen / sizeof(wchar_t)));
        boost::algorithm::split(innards, sourceRange, std::bind1st(std::equal_to<wchar_t>(), L'\n'));
        std::for_each(innards.begin(), innards.end(), std::bind(boost::algorithm::to_lower<std::wstring>, _1, std::locale()));
        std::for_each(innards.begin(), innards.end(), [&replacements] (std::wstring &a) {
            std::for_each(replacements.begin(), replacements.end(), [&a] (std::pair<std::wstring, std::wstring> const&b) {
                if (boost::algorithm::starts_with(a, b.first))
                {
                    a.replace(a.begin(), a.begin() + b.first.size(), b.second);
                }
            });
        });
        std::sort(innards.begin(), innards.end());
    }

    bool Whitelist::IsOnWhitelist( std::wstring checked ) const
    {
        boost::algorithm::to_lower(checked);
        return std::binary_search(innards.begin(), innards.end(), checked);
    }

    void Whitelist::PrintAll( std::wostream & str ) const
    {
        std::copy(innards.begin(), innards.end(), std::ostream_iterator<std::wstring, wchar_t>(str, L"\n"));
    }

}

残念ながら、Dev11のテストプロジェクトは、Google Testのシステムのように、EXEではなくDLLを生成します。そのため、リソースをEXEに埋め込んで、の最初のパラメーターに渡すことができる前は、VisualStudioNULLFindResourceテスト中にDLLをプロセスにロードしています。Visual Studioには確かにカスタムWHITELISTリソースタイプが含まれていないため、このコードは爆発的に増加します。

私ができる方法はありますか

  1. コンテキストに応じて、テストDLLまたはEXEのいずれかで、適切なバイナリを調べるようにこのコードに指示しますか?(現在、このコードは、実際のEXEとテストDLLの両方にリンクされる静的ライブラリにあります)または
  2. Win32リソースインフラストラクチャをまったく使用せずに、比較的大きな(数MB)テキストファイルをC ++プログラムにきれいに埋め込みますか?

リソースをサテライトDLLに配置すること(これは合理的な解決策であった可能性があります)はオプションではないことに注意してください。このプロジェクトの要件は、単一のEXExcopyデプロイメントです。

4

1 に答える 1

0

理解した。GetCurrentModuleここでハックを使用しました->現在実行中のコードのHMODULEを取得するにはどうすればよいですか?。これにより、XxxResourceAPIに渡す必要のあるHMODULEが得られました。

于 2012-08-20T17:06:22.080 に答える