UWP平臺Taglib編譯(1)
此文已由作者鄭博授權網易雲社群釋出。
歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗
最近開始開發UWP平臺的App,專案需要用到Taglib進行音視訊檔案的標籤資訊讀寫,Google並沒有現成的Binaries可以使用;下面記錄下自己編譯的全過程。
1.工具準備:
a)Taglib原始碼:https://taglib.github.io/releases/taglib-1.10.tar.gz (這裡選用1.10版本,其他版本可以在https://taglib.github.io上下載)
b)Zlib原始碼:https://github.com/madler/zlib/archive/v1.2.8.zip (這裡選用1.2.8版本,其他版本可以在https://github.com/madler/zlib/releases上下載)
c)CMake工具:https://cmake.org/files/v3.4/cmake-3.4.1-win32-x86.exe (這裡選用3.4.1版本,因為3.4.0以後的版本才支援VS2015)
工具安裝和原始碼解壓過程不再贅述。
2.Zlib編譯:
a)點選“Browse Source...”選擇zlib原始碼的儲存目錄,點選“Browse Build...”選擇工程目錄(這裡不建議跟原始碼放在一個目錄中,因為UWP要3個平臺)
b)點選“Configure”這是會彈出一個選擇compiler的彈框,這裡簡單說明一下,X86選Visual Studio 14 2015,X64選Visual Studio 14 2015 Win64,ARM選Visual Studio 14 2015 ARM,3個平臺均勾選Use default native compilers即可,選Finish進行確認
c)修改CMAKE_C_FLAGS,最末尾新增/DWINAPI_FAMILY=WINAPI_FAMILY_APP /D_WIN32_WINNT=0x0A00
d)修改CMAKE_C_STANDARD_LIBRARIES,清空全部欄位,填寫WindowsApp.lib
e)修改各種INSTALL路徑,改成自己的目標目錄即可,不再贅述
f)點選Generate,在工程目錄裡開啟zlib.sln,右鍵INSTALL工程,Build完Zlib就編譯完成了,3個平臺方法一致
3.Taglib編譯:
a)同zlib
b)同zlib
c)修改CMAKE_C_FLAGS & CMAKE_CXX_FLAGS,最末尾新增/D_UNICODE /DUNICODE /DWINAPI_FAMILY=WINAPI_FAMILY_APP /D_WIN32_WINNT=0x0A00
d)修改CMAKE_C_STANDARD_LIBRARIES & CMAKE_CXX_STANDARD_LIBRARIES,清空全部欄位,填寫WindowsApp.lib
e)勾選ENABLE_STATIC
f)配置ZLIB_INCLUDE_DIR/ZLIB_LIBRARY_DEBUG/ZLIB_LIBRARY_RELEASE
g)修改各種INSTALL路徑,改成自己的目標目錄即可,不再贅述
h)點選Generate生成工程檔案
因為Taglib在檔案操作時使用了CreateFileW,但是這些介面UWP上是禁止使用的,我們要修改taglib\toolkit\tfilestream.cpp,完整修改程式碼如下:
/***************************************************************************
copyright : (C) 2002 - 2008 by Scott Wheeler
email : [email protected]
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include "tfilestream.h"
#include "tstring.h"
#include "tdebug.h"
#ifdef _WIN32
# include
#else
# include
# include
#endif
#ifdef _WIN32
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
# include
/*
convert string to wstring
*/
std::wstring c2w(const char *data)
{
int size = MultiByteToWideChar(CP_UTF8, 0, data, -1, nullptr, 0);
if (size > 0) {
auto wstr = std::make_unique(size);
if (MultiByteToWideChar(CP_UTF8, 0, data, -1, wstr.get(), size) > 0) {
return std::wstring(wstr.get());
}
}
return std::wstring(L"");
}
#endif
#endif
using namespace TagLib;
namespace
{
#ifdef _WIN32
// Uses Win32 native API instead of POSIX API to reduce the resource consumption.
typedef FileName FileNameHandle;
typedef HANDLE FileHandle;
const FileHandle InvalidFileHandle = INVALID_HANDLE_VALUE;
inline FileHandle openFile(const FileName &path, bool readOnly)
{
const DWORD access = readOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
const wchar_t *fp = NULL;
std::wstring wstr = path.wstr();
if (!wstr.empty())
fp = wstr.c_str();
else if (!path.str().empty()) {
wstr = c2w(path.str().c_str());
if (!wstr.empty())
fp = wstr.c_str();
}
if (fp)
return CreateFile2(fp, access, FILE_SHARE_READ, OPEN_EXISTING, NULL);
#else
if(!path.wstr().empty())
return CreateFileW(path.wstr().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
else if(!path.str().empty())
return CreateFileA(path.str().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
#endif
else
return InvalidFileHandle;
}
inline void closeFile(FileHandle file)
{
CloseHandle(file);
}
inline size_t readFile(FileHandle file, ByteVector &buffer)
{
DWORD length;
if(ReadFile(file, buffer.data(), static_cast(buffer.size()), &length, NULL))
return static_cast(length);
else
return 0;
}
inline size_t writeFile(FileHandle file, const ByteVector &buffer)
{
DWORD length;
if(WriteFile(file, buffer.data(), static_cast(buffer.size()), &length, NULL))
return static_cast(length);
else
return 0;
}
#else // _WIN32
struct FileNameHandle : public std::string
{
FileNameHandle(FileName name) : std::string(name) {}
operator FileName () const { return c_str(); }
};
typedef FILE* FileHandle;
const FileHandle InvalidFileHandle = 0;
inline FileHandle openFile(const FileName &path, bool readOnly)
{
return fopen(path, readOnly ? "rb" : "rb+");
}
inline void closeFile(FileHandle file)
{
fclose(file);
}
inline size_t readFile(FileHandle file, ByteVector &buffer)
{
return fread(buffer.data(), sizeof(char), buffer.size(), file);
}
inline size_t writeFile(FileHandle file, const ByteVector &buffer)
{
return fwrite(buffer.data(), sizeof(char), buffer.size(), file);
}
相關文章:
【推薦】 從golang的垃圾回收說起(上篇)
【推薦】 2018中國雲原生使用者大會:網易雲深度解析微服務框架