7

I am trying to get the graphics examples to work from Stroustrup's Principles and Practices ...C++, to no avail (yet). I have installed the fltk stuff, and know that is working fine as I managed to get a window to display using with a program suggested in the appendix of his book:

#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Window.H>

int main(){

    Fl_Window window(200,200, "title here");
    Fl_Box box(0,0,200,200,"Hey, hello wrld");
    window.show();
    return Fl::run();
}

However, trying my own using his Simple_window.h (can be found on his site) gives "reference to ‘Window’ is ambiguous", since it's already at usr/include/X11/X.h . So I tried specifying the namespace to the relevant one:

struct Simple_window : Graph_lib::Window {  //Changed Window to inc. namespace
    Simple_window(Point xy, int w, int h, const string& title );

    bool wait_for_button(); // simple event loop

.
.
.

But this gives me a bunch more errors I don't understand:

$ clear; g++ -Wno-deprecated window.cpp -o holz
    /tmp/ccIFivNg.o: In function `main':
    window.cpp:(.text+0x64): undefined reference to `Simple_window::Simple_window(Point, int, int, String const&)'
    /tmp/ccIFivNg.o: In function `Graph_lib::Window::~Window()':
    window.cpp:(.text._ZN9Graph_lib6WindowD2Ev[_ZN9Graph_lib6WindowD5Ev]+0x14): undefined reference to `vtable for Graph_lib::Window'

etc.

I feel mastering graphics is going to be a long and rocky road -_-

4

6 回答 6

5

对于处于同样困境中的任何人,我将在这里留下我所做的,最终能够在 Stroustrup 的书“编程:使用 C++ 的原理和实践,第 2 版”的第 12.3 节中使用 FLTK 编译并获得第一个程序的窗口。

在 Kubuntu 14.04 上安装 FLTK 之后

$ sudo apt install libfltk1.3-dev

我可以使用以下命令编译附录 D 中的示例程序

$ fltk-config --compile fltkTest.cpp

多亏了这篇文章,我终于可以看到如何通过第 12 章的第一个示例将其走上正轨。将 cwivagg 和 Nathan 的命令与使用 fltk-config 生成的命令进行比较,我以这个命令结束

$ clang++ -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/freetype2 -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -g -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -Wl,-Bsymbolic-functions -lfltk_images -lfltk -lX11 -std=c++11 -o 's12_3_first' 's12_3_first.cpp' Simple_window.cpp Graph.cpp GUI.cpp Window.cpp

我不得不添加 -lfltk_images 和 -std=c++11

但是,现在我不得不处理编译器给我的错误。为了获得一个工作程序,我必须对 Stroustrup 在http://www.stroustrup.com/Programming/PPP2code/上提供的源代码进行几处更改

  1. 我在 Graph.h 上取消了 std_lib_facilities.h 的注释
  2. 为了解决 Window 的歧义,我需要在 Simple_window.h 的第 9 行指定 Graph_lib::Window
  3. 当 i 无符号时,第 107 行和第 113 行的 std_lib_facilities.h 使用 i<0 比较(但这些只是警告)。
  4. Graph.h 第 159 行使用 fl_color() 但编译器说它应该是 Fl_Color
  5. 我需要取消注释 Point.h 中 Point 的构造函数
  6. Simple_window.cpp 的 Simple_window.h 有几个重新定义 在 Simple_window.cpp 上,我注释掉了构造函数 cb_next 和 wait_for_button 的定义(与 Simple_window.h 上的定义不同)。在 Simple_window.h 上,我注释掉了 wait_for_button 和 next 的定义。顺便说一句,wait_for_button 在这两种形式下都不起作用。
  7. 在 GUI.cpp 中,Menu 的构造函数有另一个重新定义。我把它注释掉了。
  8. 我将第 12.3 节示例的最后一行从 win.wait_for_button 更改为;到 Fl::run(); 这是我从附录 D 的示例中获取的,因为否则窗口不会使用其关闭按钮关闭。

通过所有这些更改,我终于拥有了应有的窗口,并且使用 Next 按钮或所述窗口的关闭按钮关闭了窗口(使用 wait_for_button 我需要在尝试后使用 Ctrl-c 从 Konsole 结束程序)使用窗口的关闭按钮将其关闭)。

我希望下一个人不必花费我所有的时间。

编辑:嗯,检查我的系统和编译命令,我意识到有几个重复的地毯......而且它们实际上不存在于我的 Kubuntu 系统中。所以,我必须在我的回答中写下我最终为使窗口正常工作所做的事情:

获取目标文件:

$ clang++ -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -g -std=c++11 -c  Simple_window.cpp

获得我们想要的第一个程序

% clang++ -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -Wl,-Bsymbolic-functions -lfltk_images -lfltk -lX11 -g -std=c++11 Simple_window.o Graph.o GUI.o Window.o -o z3 s12_3_first.cpp

这些要容易得多(我几乎可以在每次需要它们时编写它们)

于 2016-03-31T01:23:04.037 回答
1

好吧,这与图形本身没有任何关系。问题似乎是您只在命令行中包含了您需要编译的源文件之一。从他的网站来看

g++ graph.cpp GUI.cpp Simple_window.cpp Window.cpp

似乎更喜欢它。但我没有这方面的实际经验。

于 2011-08-20T19:20:32.180 回答
1

Tomolak,当你说这“取得了进展”时,我非常高兴。不知道你是不是在讽刺,但无论如何。

我已经解决了这个问题(或者至少我设法让一个窗口出现了一个三角形)。然而,这只是在注释掉并编辑了 Stroustrup 的大部分代码之后。我不觉得他的书很适合初学者。我也不建议尝试使用 Linux 编译他的任何示例。

对于任何在谷歌上搜索这些问题的人,我的最终解决方案是这个命令:

$ g++ -Wno-deprecated -I/usr/local/include -I/usr/include/freetype2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -o 'windows_working' win_test.cpp Graph.cpp GUI.cpp Simple_window.cpp Window.cpp  /usr/local/lib/libfltk.a -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11

这包括与 fltk 和 Stroustrup 相关的所有内容。在这里,我的程序是 win_test.cpp,输出是 windows_working。我通过 fltk 文件提供的 shell 脚本获得了这个结果,并将其放入 /usr/inc/bin。它被称为 fltk-config。

此外,有用的提示是:从他们的网站下载 fltk 源,而不仅仅是从 Stroustrup 的网站下载 FL 源。然后在尝试本书附录 D 中的测试程序之前阅读自述文件并严格按照说明进行操作。然后尝试他的示例代码反复修复您发现的错误,直到它工作。如果您认为我可以提供帮助或想知道我是如何获得解决方案的,请给我发电子邮件(但我是新手,因此不太可能有用)。

于 2011-08-21T19:48:02.063 回答
1

弥敦道,

在我自己努力实现 Stroustrup 的简单三角形程序时,您的回答对我非常有帮助。我想根据你的发布我自己的解决方案。通过对 Stroustrup 的代码进行一次更改和大大扩展的编译脚本,我得到了三角形出现。

g++ -I/usr/localinclude -I/usr/local/include/FL/images -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT -o 'myimplementationofstroustrup.o' 'myimplementationofstroustrup.cpp' 'Simple_window.cpp' 'Graph.cpp' 'GUI.cpp' 'Window.cpp' /usr/local/lib/libfltk.a -lpthread -ldl -lm -lX11 -L/usr/local/lib -lfltk_images -lfltk_png -lfltk_z -lfltk_jpeg -lfltk

与你的不同之处如下:

1)我必须在我的所有 .cpp 文件中添加引号......也许是系统差异?
2) 我必须在最后添加六个你没有使用的标志,否则我会得到更多“未定义的引用”错误。
3) 由于不明确的引用错误,我不得不在 Simple_window.h 的第 17 行指定“Graph_lib::Window”。这是我必须对 Stroustrup 的代码进行的唯一更改。

于 2014-07-10T12:09:36.683 回答
0

在本书论坛的一个线程中有一个非常详细的演练如何解决这个问题:
https ://groups.google.com/forum/#!msg/ppp-public/BtlzdWGuQpQ/KuDN4u-SPKgJ

在此基础上,我创建了一个 github 存储库,它实现了所有这些更改以及更多内容,并包含有关如何构建项目的详细信息:

https://github.com/cortical-iv/hello_fltk

我在这个问题上花了大约两个星期的时间,我的知识(主要是从别人那里获得的)坦率地体现在代码中,并且会不断更新。但这是堆栈溢出,所以就我必须对代码进行的更改而言,大多数都可以在那个论坛上找到,但由于给出链接答案并不好,所以它们是:

Simple_window.h

  1. 解决命名空间冲突更改struct Simple_window : Window {
    struct Simple_window : Graph_lib::Window {

  2. Simple_window() 转换为声明(删除定义)。

  3. wait_for_button()从定义转换为声明(在 while 循环中注释掉整个 def)并从 void 更改为 bool 以与Simple_window.cpp.

  4. 转向cb_next(...)声明

  5. 转向void next()声明

Graph.h
1. 取消注释#include "std_lib_facilities.h"
2. 更改fl_colorFl_Color(~ 第 159 行)

Graph.cpp 1. 替换can_open为: bool can_open(const string& s) // 检查是否存在名为 s 的文件,是否可以打开读取 { ifstream ff(s); 返回 ff.is_open(); }

Point.h
1. 取消注释构造函数

Point(int xx, int yy) : x(xx), y(yy) { }    
Point() :x(0), y(0) { }

Gui.h
1. 在 Menu : Widget 中,将 Menu(Point xy ...) 更改为声明而不是 def,注释掉 Widget def 的东西。

完成上述操作后,如果您在终端上运行以下命令,它应该可以编译:

g++ -w -Wall -std=c++11 Graph.cpp Window.cpp GUI.cpp Simple_window.cpp main.cpp `fltk-config --ldflags --use-images` -o hello_fltk

如果您使用 cmake 安装了 fltk,那么您也可以使用 cmake/make 构建示例:CMakeLists.txt存储库中有一个文件。

于 2018-06-12T03:44:33.863 回答
0

这个问题和修复的总结对于让它在不同的平台上工作也很有帮助。实际更正的代码可供下载:

FLTK 问题编译 - PPP2ndEd

于 2017-07-11T18:39:03.173 回答