【问题标题】:c++ bass and rapidXml on Raspberry Pi 1 BRaspberry Pi 1 B 上的 c++ bass 和 rapidXml
【发布时间】:2015-12-21 21:08:30
【问题描述】:

我在为我的孩子们做的一个项目中有一个奇怪的行为。我想用 rapidXml 解析一个 xml,并在我的 RasPi1B 上用贝司播放 mp3。如果我只是在一个主功能中按下它,一切都很好。但是,只要我将代码放入另一个类,我的 xml 数据就会损坏。 我只在私人时间使用 c++ 并使用托管语言,所以我不太喜欢 c++ 中的内存管理。所以我希望你们能帮助我(和我的孩子)解决这个问题。当然我可以在一节课上做所有事情,但是大脑会试图让我窒息而死;-)

首先在单个主函数中:

// test.cpp

#include <iostream>
#include <rapidxml.hpp>
#include <rapidxml_utils.hpp>
#include <rapidxml_print.hpp>
#include <bass.h>

using namespace std;
using namespace rapidxml;

int main(int argc, char **argv)
{
    file<> xmlFile("bin/test.xml");

    xml_document<> doc;
    doc.parse<0>(xmlFile.data());

    print(std::cout, doc, 0); // everything is fine

    bool init = BASS_Init(-1, 44100, 0, 0, NULL);
    cout << "BASS_Init " << (init ? "true" : "false") << " [error: " << BASS_ErrorGetCode() << "]" << endl;

    print(std::cout, doc, 0); // everything is fine

    return 0;
}

然后(几乎)与 main 函数和类/标题相同:

//test2.cpp

#include <iostream>

#include "player.hpp"

using namespace std;
using namespace player;

int main(int argc, char **argv)
{
    Player* _pPlayer = new Player();
    _pPlayer->loadXml();

    _pPlayer->printXml();       
    _pPlayer->initPlayer();
    _pPlayer->printXml();

    return 0;
}



// player.cpp

#include "player.hpp"

using namespace std;
using namespace rapidxml;

namespace player {
    void Player::loadXml(void)
    {
        file<> xmlFile("bin/test.xml");
        doc.parse<0>(xmlFile.data());
    }

    void Player::printXml(void)
    {
        print(std::cout, doc, 0);
    }

    void Player::initPlayer(void)
    {
        bool init = BASS_Init(-1, 44100, 0, 0, NULL);
        cout << "BASS_Init " << (init ? "true" : "false") << " [error: " << BASS_ErrorGetCode() << "]" << endl;
    }
}



// player.hpp

#include <iostream>

#include <rapidxml.hpp>
#include <rapidxml_utils.hpp>
#include <rapidxml_print.hpp>
#include <bass.h>

using namespace std;
using namespace rapidxml;

namespace player {
    class Player
    {
        public:
            void loadXml(void);
            void printXml(void);
            void initPlayer(void);
        private:
            xml_document<> doc;
    };
}

编译:

BASS_PATH = ../libraries/bass_arm
BASS_INCLUDE_PATH = -I$(BASS_PATH)
BASS_LIBRARY_PATH = -L$(BASS_PATH) -L$(BASS_PATH)/hardfp
BASS_LIBS = -lbass -lm
BASS_LINKER_FLAGS = -Wl,-rpath,$(BASS_PATH):$(BASS_PATH)/hardfp

RAPIDXML_PATH = ../libraries/rapidxml-1.13
RAPIDXML_INCLUDE_PATH = -I$(RAPIDXML_PATH)
RAPIDXML_LIBRARY_PATH = -L$(RAPIDXML_PATH)

test:
    g++ -std=c++11 src_test/test.cpp -o bin/test $(BASS_INCLUDE_PATH) $(RAPIDXML_INCLUDE_PATH) $(BASS_LIBRARY_PATH) $(RAPIDXML_LIBRARY_PATH) $(BASS_LIBS) $(BASS_LINKER_FLAGS)

test2:
    g++ -std=c++11 -g -c src_test/test2.cpp -o src_test/test2.o $(BASS_INCLUDE_PATH) $(RAPIDXML_INCLUDE_PATH)
    g++ -std=c++11 -g -c src_test/player.cpp -o src_test/player.o $(BASS_INCLUDE_PATH) $(RAPIDXML_INCLUDE_PATH)
    g++ -std=c++11 -g src_test/test2.o src_test/player.o -o bin/test2 $(BASS_LIBRARY_PATH) $(RAPIDXML_LIBRARY_PATH) $(BASS_LIBS) $(BASS_LINKER_FLAGS)

我的 test.xml 看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<library>
    <series>
        <title>Lorem ipsum A</title>
        <episode>
            <title>dolor sit amet 1</title>
            <cover></cover>
            <files rfid="x1" current_file="1" timestamp="0">
                <file>consetetur/sadipscing_elitr_11.mp3</file>
                <file>consetetur/sadipscing_elitr_12.mp3</file>
                <file>consetetur/sadipscing_elitr_13.mp3</file>
                <file>consetetur/sadipscing_elitr_14.mp3</file>
            </files>
        </episode>
        <episode>
            <title>dolor sit amet 2</title>
            <cover></cover>
            <files rfid="x2" current_file="1" timestamp="0">
                <file>consetetur/sadipscing_elitr_21.mp3</file>
                <file>consetetur/sadipscing_elitr_22.mp3</file>
                <file>consetetur/sadipscing_elitr_23.mp3</file>
                <file>consetetur/sadipscing_elitr_24.mp3</file>
            </files>
        </episode>
    </series>
</library>

这是 sudo bin/test

的输出
<library>
        <series>
                <title>Lorem ipsum A</title>
                <episode>
                        <title>dolor sit amet 1</title>
                        <cover/>
                        <files rfid="x1" current_file="1" timestamp="0">
                                <file>consetetur/sadipscing_elitr_11.mp3</file>
                                <file>consetetur/sadipscing_elitr_12.mp3</file>
                                <file>consetetur/sadipscing_elitr_13.mp3</file>
                                <file>consetetur/sadipscing_elitr_14.mp3</file>
                        </files>
                </episode>
                <episode>
                        <title>dolor sit amet 2</title>
                        <cover/>
                        <files rfid="x2" current_file="1" timestamp="0">
                                <file>consetetur/sadipscing_elitr_21.mp3</file>
                                <file>consetetur/sadipscing_elitr_22.mp3</file>
                                <file>consetetur/sadipscing_elitr_23.mp3</file>
                                <file>consetetur/sadipscing_elitr_24.mp3</file>
                        </files>
                </episode>
        </series>
</library>
BASS_Init true [error: 0]
<library>
        <series>
                <title>Lorem ipsum A</title>
                <episode>
                        <title>dolor sit amet 1</title>
                        <cover/>
                        <files rfid="x1" current_file="1" timestamp="0">
                                <file>consetetur/sadipscing_elitr_11.mp3</file>
                                <file>consetetur/sadipscing_elitr_12.mp3</file>
                                <file>consetetur/sadipscing_elitr_13.mp3</file>
                                <file>consetetur/sadipscing_elitr_14.mp3</file>
                        </files>
                </episode>
                <episode>
                        <title>dolor sit amet 2</title>
                        <cover/>
                        <files rfid="x2" current_file="1" timestamp="0">
                                <file>consetetur/sadipscing_elitr_21.mp3</file>
                                <file>consetetur/sadipscing_elitr_22.mp3</file>
                                <file>consetetur/sadipscing_elitr_23.mp3</file>
                                <file>consetetur/sadipscing_elitr_24.mp3</file>
                        </files>
                </episode>
        </series>
</library>

以及sudo bin/test2的输出:

<library>
        <series>
                <title>Lorem ipsum A</title>
                <episode>
                        <title>dolor sit amet 1</title>
                        <cover/>
                        <files rfid="x1" current_file="1" timestamp="0">
                                <file>consetetur/sadipscing_elitr_11.mp3</file>
                                <file>consetetur/sadipscing_elitr_12.mp3</file>
                                <file>consetetur/sadipscing_elitr_13.mp3</file>
                                <file>consetetur/sadipscing_elitr_14.mp3</file>
                        </files>
                </episode>
                <episode>
                        <title>dolor sit amet 2</title>
                        <cover/>
                        <files rfid="x2" current_file="1" timestamp="0">
                                <file>consetetur/sadipscing_elitr_21.mp3</file>
                                <file>consetetur/sadipscing_elitr_22.mp3</file>
                                <file>consetetur/sadipscing_elitr_23.mp3</file>
                                <file>consetetur/sadipscing_elitr_24.mp3</file>
                        </files>
                </episode>
        </series>
</library>

BASS_Init true [error: 0]
<l1▒B>
        CJ>
                <>▒CJ▒BJ▒BJ</>
                <device>
                        <de>aults.pcm.device</de>
                        <`CJ/>
                        <8CJ BJ="" iec958="1" 1▒CJ="">
                                <>▒DJ▒BJ6Jcardp3</>
                                <ults>pcm.cardr/1▒CJ▒CJ</ults>
                                <▒CJ>devicesg_edefault</▒CJ>
                                <1>DJPDJ▒CJ(DJ▒CJ</1>
                        </8CJ>
                </device>
                <EJpE>
                        <▒>J▒CJ6J</▒>
                        <cover/>
                        <cm.ca did="" J▒DJ="" pEJ="J">
                                <>devicesdipdefaults.pcm.d</>
                                <>@EJ▒DJEJ▒DJ</>
                                <rmat>rawur/sadip1▒EJ▒EJ</rmat>
                                <▒DJ>6Jtrueltstr_fi</▒DJ>
                        </cm.ca>
                </EJpE>
        <CJ>
</l1▒B>

抱歉,帖子太长了!我希望有一个人可以帮助我。我真的觉得很失落... 提前致谢!

【问题讨论】:

    标签: c++ xml raspberry-pi rapidxml bass


    【解决方案1】:

    xmlFile 在Player::loadXml() 超出范围时被销毁。这允许将xmlFile 的数据占用的内存分配给其他东西(在这种情况下BASE_Init 似乎正在向其写入数据)。

    doc 仍在使用 xmlFile 以前的数据。这会导致未定义的行为。

    请将xmlFile 存储在Player 类中,就像使用doc 一样。

    也不要忘记delete new 的所有内容,比如 _pPlayer ;-)

    【讨论】:

    • 哦,是的,你成就了我的一天!我一直认为,在 doc.parse() 之后不使用 xmlFile ......尽管,这个 rapidxml_utils (其中定义了 file )也给了我一些艰难的时间,因为我不知道如何处理整个模板的东西(还没有在模板中,但看起来有点像 java 中的泛型)。我通过将file&lt;&gt;* pXmlFile; 添加到.hpp 并将pXmlFile = new file&lt;&gt;("bin/test.xml"); 添加到.cpp 来解决它。到目前为止工作正常,但它是正确的方法吗? (编辑:cmets 中的不良格式选项^^)
    • 另外作为补充:是的,在我的“生产代码”中,我使用delete。我只是想让示例尽可能简短。
    • 使用指向file&lt;&gt;* 的指针是正确的a。另一种方法可能是没有指针,使用Player 的构造函数来初始化你的file&lt;&gt; xmlFile。在 Player 类中的 public: 之后,您可以添加:Player() : xmlFile("bin/test.xml") {}
    • 再次感谢!我可以以正确的方式接受a ;-) 我知道大多数时候不止一种好方法。我故意不使用构造函数方法,因为在“真实”程序中,加载的 xml 因用户使用应用程序而异。但是,是的,我也想过这个解决方案。无论如何,指针就像一个魅力,我很高兴继续有效地在我的小项目上工作。我尝试解决这个错误将近 3 周(不是每天,而是在晚上……但它变得很烦人)。所以最后一次我不得不说:非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 2018-12-28
    相关资源
    最近更新 更多