You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

静态链接libMatroska并使用时的编译与符号解析问题

问题描述

我需要通过编程提取.mkv文件的元数据,libMatroska看起来是合适的工具。目前没有可用的预编译库,所以我用CMake自行编译了libEBML和libMatroska,得到了libmatroska.a和libebml.a文件,但不确定是否需要libebml.a。

现在尝试在项目中静态链接这些库,但IDE无法识别matroska/FileKax.h(该目录有效,且IDE能识别同目录下的其他libMatroska头文件,#include "matroska/FileKax.h"语句在IDE中呈灰色)。我对CMake不太熟悉,而且几乎找不到关于如何在项目中使用libMatroska的文档。

测试项目目录结构

项目根目录
├── ebml/          # 包含libEBML头文件及生成的ebml_export.h
├── matroska/      # 包含libMatroska头文件及生成的matroska_export.h
├── libebml.a
├── libmatroska.a
├── main.cpp
└── CMakeLists.txt

当前CMakeLists.txt内容

cmake_minimum_required(VERSION 3.28)
project(mkv_metadata_test)

set(CMAKE_CXX_STANDARD 26)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/matroska)

set(MATROSKA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/matroska")
set(MATROSKA_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libmatroska.a")


set(EBML_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ebml")
set(EBML_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/libebml.a")

add_library(matroska STATIC IMPORTED)
set_target_properties(matroska PROPERTIES IMPORTED_LOCATION ${MATROSKA_LIB_PATH}/libmatroska.a)

add_executable(mkv_metadata_test main.cpp)

target_link_libraries(mkv_metadata_test PRIVATE matroska)

FileKax.h文件内容

/*!
  \file
  \version \$Id: FileKax.h,v 1.5 2004/04/14 23:26:17 robux4 Exp $
  \author Steve Lhomme     <robux4 @ users.sf.net>
*/
#ifndef LIBMATROSKA_FILE_H
#define LIBMATROSKA_FILE_H

//#include <vector>

#include "matroska/KaxTypes.h"
#include "ebml/IOCallback.h"
//#include "MainHeader.h"
//#include "TrackType.h"
//#include "StreamInfo.h"
//#include "Cluster.h"
//#include "CodecHeader.h"

using namespace libebml;

namespace libmatroska {

//class Track;
//class Frame;

/*!
    \class MATROSKA_DLL_API FileMatroska
    \brief General container of all the parameters and data of an Matroska file
    \todo Handle the filename and next filename
    \todo Handle the IOCallback selection/type
*/
class MATROSKA_DLL_API FileMatroska {
    public:
    FileMatroska(IOCallback & output);
    ~FileMatroska() = default;
#ifdef OLD
  filepos_t RenderHead(const std::string & aEncoderApp);
  uint32 ReadHead();
  uint32 ReadTracks();
  uint32 ReadCodec();
  void Close(const uint32 aTimeLength);

  inline void type_SetInfo(const std::string & aStr) {myMainHeader.type_SetInfo(aStr);}
  inline void type_SetAds(const std::string & aStr) {myMainHeader.type_SetAds(aStr);}
  inline void type_SetSize(const std::string & aStr) {myMainHeader.type_SetSize(aStr);}
  inline void type_SetSize(uint64 aSize) {myMainHeader.type_SetSize(aSize);}

  inline uint8 GetTrackNumber() const { return myTracks.size(); }

  void track_SetName(Track * aTrack, const std::string & aName);
  void track_SetLaced(Track * aTrack, bool bLaced = true);

  Track * CreateTrack(const track_type aType);
  inline Track * GetTrack(const uint8 aTrackNb) const
  {
      if (aTrackNb > myTracks.size())
    return NULL;
      else
    return myTracks[aTrackNb-1];
  }

  void Track_GetInfo(const Track * aTrack, TrackInfo & aTrackInfo) const;

  void Track_SetInfo_Audio(Track * aTrack, const TrackInfoAudio & aTrackInfo);
  void Track_GetInfo_Audio(const Track * aTrack, TrackInfoAudio & aTrackInfo) const;

  void Track_SetInfo_Video(Track * aTrack, const TrackInfoVideo & aTrackInfo);
  void Track_GetInfo_Video(const Track * aTrack, TrackInfoVideo & aTrackInfo) const;

  void SelectReadingTrack(Track * aTrack, bool select = true);

  /*!
      \return wether the frame has been added or not
  */
  bool AddFrame(Track * aTrack, const uint32 aTimecode, const binary *aFrame, const uint32 aFrameSize,
         bool aKeyFrame = true, bool aBFrame = false);

  /*!
      \return wether the frame has been read or not
  */
  bool ReadFrame(Track * & aTrack, uint32 & aTimecode, const binary * & aFrame, uint32 & aFrameSize,
         bool & aKeyFrame, bool & aBFrame);

  /*
      Render the pending cluster to file
  */
  void Flush();

  void SetMaxClusterSize(const uint32 value);
  void SetMinClusterSize(const uint32 value) {myMinClusterSize = value;}

    protected:
  MainHeader myMainHeader;

  std::vector<Track *> myTracks;
  std::vector<uint8> mySelectedTracks;

//  Track *findTrack(Track * aTrack) const;

  Cluster  myCurrWriteCluster; /// \todo merge with the write one ?
  uint32   myReadBlockNumber;
  Cluster  myCurrReadCluster;
  binary * myCurrReadBlock;      ///< The buffer containing the current read block
  uint32   myCurrReadBlockSize;  ///< The size of the buffer containing the current read block
  uint8    myCurrReadBlockTrack; ///< The track number of the current track to read

  uint32 myMaxClusterSize;
  uint32 myMinClusterSize;

  StreamInfo myStreamInfo;

  CodecHeader myCodecHeader;

  inline bool IsMyTrack(const Track * aTrack) const;
  inline bool IsReadingTrack(const uint8 aTrackNum) const;
#endif // OLD
  IOCallback & myFile;

};

} // namespace libmatroska

#ifdef __cplusplus
extern "C" {
#endif

MATROSKA_DLL_API void matroska_init();
MATROSKA_DLL_API void matroska_done();

#ifdef __cplusplus
}
#endif

#endif // FILE_KAX_HPP

当前遇到的错误

  • 符号FileMatroska无法解析
  • main.cpp报错KaxCuePoint类型不完整

内容的提问来源于stack exchange,提问作者memeko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:44:56