将 libxml++ 和 glib 库与适用于 C++ Windows 的 CodeBlocks IDE 链接的问题

2022-01-20 00:00:00 compilation ide linker c++ codeblocks

我正在使用 Code Blocks IDE 为 Windows 编写 C++ 应用程序.我有兴趣使用以下 XML++ 库:.我找不到 glibmm 的预构建 Windows 二进制文件,因此您要么必须下载整个 gtkmm 安装程序,或 自己构建.

这个过程完成后,你应该有像这样的文件

libxml2.liblibxml2.alibxml2.dll

根据您的编译器(GCC 或 MSVC)以及所需的链接方法(静态或动态),您应该选择所需的库文件.

在 Code::Blocks 中,您可以通过链接器设置"选项卡进行链接,可通过 Project -> 访问.构建选项... ->链接器设置.点击add,选择之前编译好的使用文件夹浏览器的库文件(libxml2glibmm-2.4libxml++).

更新:我能够在我的 Windows 8 64 位 PC 上成功运行该项目.

我从 MinGW-builds (GCC 4.8.1) 安装了 MinGW-64.我唯一需要下载的是 gtkmm-win64 安装程序.我选择了完整安装".

项目构建设置中的搜索目录为:

C:gtkmm64includeC:gtkmm64includelibxml++-2.6C:gtkmm64includeglibmm-2.4C:gtkmm64includeglib-2.0C:gtkmm64libglibmm-2.4includeC:gtkmm64libglib-2.0includeC:gtkmm64liblibxml++-2.6include

要链接的导入库是:

C:gtkmm64liblibxml++-2.6.dll.aC:gtkmm64liblibglibmm-2.4.dll.aC:gtkmm64liblibglibmm_generate_extra_defs-2.4.dll.a

DLL 从 gtkmm64in 文件夹复制到可执行文件的位置是:

libglib-2.0-0.dlllibglibmm-2.4-1.dlllibglibmm_generate_extra_defs-2.4-1.dlllibxml++-2.6-2.dlllibxml2-2.dll

可执行文件成功运行(不包括程序由于某些解析异常而终止的事实).

I am writing a C++ app for Windows using Code Blocks IDE. I am interested in using the following XML++ library: http://libxmlplusplus.sourceforge.net/

It requires libxml2 and glibmm-2.4 libraries. I downloaded the source for each of these libraries and included all of the headers into my project by right clicking on "Build Options" ==> "Search Directories" tab ==> "Compiler" tab. I specified the header include files there. I modified the main.cpp file using the source code from "examples/dom_parser" from the xml++/examples directory.

Now, I am having trouble with the following error message. I have never "linked" or used *.lib, *.dll files before... but I am now getting the following "undefined reference" error messages. Please let me know what I'd need to do in order to build this. Is there a particular file that I need to "link" and if so, where are these files located? I can't seem to find them in the source files that I extracted. Could you help with specific instructions on which files to include and which folders they might be located in? I am using the CodeBlocks IDE.

Could someone replicate the project on your Windows 64 bit PC and see if it is able to run correctly?

Thank you.

UPDATE

C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:44: undefined reference to `xmlpp::ContentNode::is_white_space() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:47: undefined reference to `xmlpp::Node::get_name() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:49: undefined reference to `Glib::ustring::empty() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:53: undefined reference to `xmlpp::Node::get_namespace_prefix() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:54: undefined reference to `Glib::ustring::empty() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:55: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `xmlpp::ContentNode::get_content() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:74: undefined reference to `xmlpp::ContentNode::get_content() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:74: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:74: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:79: undefined reference to `xmlpp::ContentNode::get_content() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:79: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:79: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:87: undefined reference to `xmlpp::Node::get_line() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:90: undefined reference to `xmlpp::Element::get_attributes() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:96: undefined reference to `xmlpp::Node::get_namespace_prefix() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:97: undefined reference to `Glib::ustring::empty() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `xmlpp::Attribute::get_value() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `xmlpp::Attribute::get_name() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `xmlpp::Attribute::get_value() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `xmlpp::Attribute::get_name() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:101: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::ustring(char const*)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `xmlpp::Element::get_attribute(Glib::ustring const&, Glib::ustring const&) const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:106: undefined reference to `xmlpp::Attribute::get_value() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:106: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:106: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:113: undefined reference to `Glib::ustring::ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:113: undefined reference to `xmlpp::Node::get_children(Glib::ustring const&) const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:113: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:118: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `Glib::ustring::~ustring()'

**UPDATED 02/11/2014 - at 10:45am **

Hi. Thanks for your suggestion. I ended up downloading the following ( http://ftp.gnome.org/pub/gnome/binaries/win32/gtkmm/2.22/ ) the entire gtkmm-win32-devel-2.22.0-2.exe and installed it onto my Windows PC in C:gtkmm. Then, I modified my project by including the header files, library files, and bin files. Here are the screen shots:

After building, I am now seeing 0 errors and 0 warning messages. However, it appears to CRASH. I have no idea why. It seems that the gtk installation uses libxml++ version 2.6. This is fine. I downloaded the libxml++ 2.6 from the website to see the examples that they provided. I used the following source code in my main.cc. Do you know what is the problem?

// -*- C++ -*-

/* main.cc
 *
 * Copyright (C) 2002 The libxml++ development team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <libxml++/libxml++.h>

#include <iostream>

void print_indentation(unsigned int indentation)
{
  for(unsigned int i = 0; i < indentation; ++i)
    std::cout << " ";
}

void print_node(const xmlpp::Node* node, unsigned int indentation = 0)
{
  std::cout << std::endl; //Separate nodes by an empty line.

  const xmlpp::ContentNode* nodeContent = dynamic_cast<const xmlpp::ContentNode*>(node);
  const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
  const xmlpp::CommentNode* nodeComment = dynamic_cast<const xmlpp::CommentNode*>(node);

  if(nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this.
    return;

  Glib::ustring nodename = node->get_name();

  if(!nodeText && !nodeComment && !nodename.empty()) //Let's not say "name: text".
  {
    print_indentation(indentation);
    std::cout << "Node name = " << node->get_name() << std::endl;
    std::cout << "Node name = " << nodename << std::endl;
  }
  else if(nodeText) //Let's say when it's text. - e.g. let's say what that white space is.
  {
    print_indentation(indentation);
    std::cout << "Text Node" << std::endl;
  }

  //Treat the various node types differently:
  if(nodeText)
  {
    print_indentation(indentation);
    std::cout << "text = "" << nodeText->get_content() << """ << std::endl;
  }
  else if(nodeComment)
  {
    print_indentation(indentation);
    std::cout << "comment = " << nodeComment->get_content() << std::endl;
  }
  else if(nodeContent)
  {
    print_indentation(indentation);
    std::cout << "content = " << nodeContent->get_content() << std::endl;
  }
  else if(const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node))
  {
    //A normal Element node:

    //line() works only for ElementNodes.
    print_indentation(indentation);
    std::cout << "     line = " << node->get_line() << std::endl;

    //Print attributes:
    const xmlpp::Element::AttributeList& attributes = nodeElement->get_attributes();
    for(xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
    {
      const xmlpp::Attribute* attribute = *iter;
      print_indentation(indentation);
      std::cout << "  Attribute " << attribute->get_name() << " = " << attribute->get_value() << std::endl;
    }

    const xmlpp::Attribute* attribute = nodeElement->get_attribute("title");
    if(attribute)
    {
      std::cout << "title found: =" << attribute->get_value() << std::endl;

    }
  }

  if(!nodeContent)
  {
    //Recurse through child nodes:
    xmlpp::Node::NodeList list = node->get_children();
    for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
    {
      print_node(*iter, indentation + 2); //recursive
    }
  }
}

int main(int argc, char* argv[])
{
  Glib::ustring filepath;
  if(argc > 1 )
    filepath = argv[1]; //Allow the user to specify a different XML file to parse.
  else
    filepath = "example.xml";

  try
  {
    xmlpp::DomParser parser;
    parser.set_validate();
    parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically.
    parser.parse_file(filepath);
    if(parser)
    {
      //Walk the tree:
      const xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser.
      print_node(pNode);
    }
  }
  catch(const std::exception& ex)
  {
    std::cout << "Exception caught: " << ex.what() << std::endl;
  }

  return 0;
}

解决方案

Are libxml2 and glibmm-2.4 built?

You can find prebuilt windows binaries for libxml2 here. I can't find prebuilt windows binaries for glibmm, so you'll either have to download the entire gtkmm installer, or build it yourself.

After this process is done, you should have files such as

libxml2.lib
libxml2.a
libxml2.dll

Depending on you compiler (GCC or MSVC), and the desired linking method (static or dynamic), you should choose the required library files.

In Code::Blocks you do the linking via the "Linker settings" tab, accessible through Project -> Build options... -> Linker settings. Click add and select the previously compiled library files (libxml2, glibmm-2.4 and libxml++) using the folder browser.

Update: I am able to successfully run the project on my Windows 8 64-bit PC.

I have a MinGW-64 installation from MinGW-builds (GCC 4.8.1). The only other thing I had to download was the gtkmm-win64 installer. I chose the "full installation".

The search directories in the project build settings were:

C:gtkmm64include
C:gtkmm64includelibxml++-2.6
C:gtkmm64includeglibmm-2.4
C:gtkmm64includeglib-2.0
C:gtkmm64libglibmm-2.4include
C:gtkmm64libglib-2.0include
C:gtkmm64liblibxml++-2.6include

The import libraries to link to were:

C:gtkmm64liblibxml++-2.6.dll.a
C:gtkmm64liblibglibmm-2.4.dll.a
C:gtkmm64liblibglibmm_generate_extra_defs-2.4.dll.a

And the DLL's copied to the executable's location from the gtkmm64in folder were:

libglib-2.0-0.dll
libglibmm-2.4-1.dll
libglibmm_generate_extra_defs-2.4-1.dll
libxml++-2.6-2.dll
libxml2-2.dll

The executable ran successfully (excluding the fact that the program terminated due to some parsing exception).

相关文章