From 9e45144d3ad1420908cfdf84306c76f637829023 Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 29 Oct 2012 19:32:05 +0000 Subject: C++ constructors work with ELF load now git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5273 42af7a65-404d-4744-a932-0658087f49c3 --- apps/examples/elf/elf_main.c | 80 +++++++++++++- apps/examples/elf/tests/helloxx/Makefile | 124 ++++++++++++++++++++++ apps/examples/elf/tests/helloxx/hello++1.cpp | 60 +++++++++++ apps/examples/elf/tests/helloxx/hello++2.cpp | 123 ++++++++++++++++++++++ apps/examples/elf/tests/helloxx/hello++3.cpp | 132 +++++++++++++++++++++++ apps/examples/elf/tests/helloxx/hello++4.cpp | 150 +++++++++++++++++++++++++++ 6 files changed, 664 insertions(+), 5 deletions(-) create mode 100644 apps/examples/elf/tests/helloxx/Makefile create mode 100644 apps/examples/elf/tests/helloxx/hello++1.cpp create mode 100644 apps/examples/elf/tests/helloxx/hello++2.cpp create mode 100644 apps/examples/elf/tests/helloxx/hello++3.cpp create mode 100644 apps/examples/elf/tests/helloxx/hello++4.cpp (limited to 'apps') diff --git a/apps/examples/elf/elf_main.c b/apps/examples/elf/elf_main.c index 23a6b2d21..669de430d 100644 --- a/apps/examples/elf/elf_main.c +++ b/apps/examples/elf/elf_main.c @@ -41,6 +41,7 @@ #include #include + #include #include #include @@ -129,6 +130,9 @@ * Private Data ****************************************************************************/ +static unsigned int g_mminitial; /* Initial memory usage */ +static unsigned int g_mmstep; /* Memory Usage at beginning of test step */ + static const char delimiter[] = "****************************************************************************"; @@ -145,6 +149,53 @@ extern const int nexports; * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: mm_update + ****************************************************************************/ + +static void mm_update(FAR unsigned int *previous, FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + printf("\nMemory Usage %s:\n", msg); + printf(" Before: %8u After: %8u Change: %8d\n", + *previous, mmcurrent.uordblks, (int)mmcurrent.uordblks - (int)*previous); + + /* Set up for the next test */ + + *previous = mmcurrent.uordblks; +} + +/**************************************************************************** + * Name: mm_initmonitor + ****************************************************************************/ + +static void mm_initmonitor(void) +{ + struct mallinfo mmcurrent; + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mminitial = mmcurrent.uordblks; + g_mmstep = mmcurrent.uordblks; + + printf("Initial memory usage: %d\n", mmcurrent.uordblks); +} + /**************************************************************************** * Name: testheader ****************************************************************************/ @@ -168,6 +219,10 @@ int elf_main(int argc, char *argv[]) int ret; int i; + /* Initialize the memory monitor */ + + mm_initmonitor(); + /* Initialize the ELF binary loader */ message("Initializing the ELF binary loader\n"); @@ -178,6 +233,8 @@ int elf_main(int argc, char *argv[]) exit(1); } + mm_update(&g_mmstep, "after elf_initialize"); + /* Create a ROM disk for the ROMFS filesystem */ message("Registering romdisk at /dev/ram%d\n", CONFIG_EXAMPLES_ELF_DEVMINOR); @@ -190,6 +247,8 @@ int elf_main(int argc, char *argv[]) exit(1); } + mm_update(&g_mmstep, "after romdisk_register"); + /* Mount the file system */ message("Mounting ROMFS filesystem at target=%s with source=%s\n", @@ -203,7 +262,9 @@ int elf_main(int argc, char *argv[]) elf_uninitialize(); } - /* Now excercise every progrm in the ROMFS file system */ + mm_update(&g_mmstep, "after mount"); + + /* Now excercise every program in the ROMFS file system */ for (i = 0; dirlist[i]; i++) { @@ -223,17 +284,26 @@ int elf_main(int argc, char *argv[]) exit(1); } + mm_update(&g_mmstep, "after load_module"); + ret = exec_module(&bin, 50); + + mm_update(&g_mmstep, "after exec_module"); + if (ret < 0) { err("ERROR: Failed to execute program '%s'\n", dirlist[i]); - unload_module(&bin); + } + else + { + message("Wait a bit for test completion\n"); + sleep(4); } - message("Wait a bit for test completion\n"); - sleep(4); + unload_module(&bin); + mm_update(&g_mmstep, "after unload_module"); } - message("End-of-Test.. Exiting\n"); + mm_update(&g_mmstep, "End-of-Test"); return 0; } diff --git a/apps/examples/elf/tests/helloxx/Makefile b/apps/examples/elf/tests/helloxx/Makefile new file mode 100644 index 000000000..d115fbeaf --- /dev/null +++ b/apps/examples/elf/tests/helloxx/Makefile @@ -0,0 +1,124 @@ +############################################################################ +# examples/elf/tests/helloxx/Makefile +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs + +BIN1 = hello++1 +BIN2 = hello++2 +ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y) +BIN3 = hello++3 +endif +#BIN4 = hello++4 +ALL_BIN = $(BIN1) $(BIN2) $(BIN3) $(BIN4) + +SRCS1 = $(BIN1).c +OBJS1 = $(SRCS1:.c=.o) + +SRCS2 = $(BIN2).c +OBJS2 = $(SRCS2:.c=.o) + +ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y) +SRCS3 = $(BIN3).c +OBJS3 = $(SRCS3:.c=.o) +endif + +#SRCS4 = $(BIN4).c +#OBJS4 = $(SRCS4:.c=.o) + +SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) + +LIBSTDC_STUBS_DIR = $(TOPDIR)/libxx +LIBSTDC_STUBS_LIB = $(LIBSTDC_STUBS_DIR)/liblibxx.a + +all: $(BIN1) $(BIN2) $(BIN3) $(BIN4) + +$(OBJS): %.o: %.cpp + @echo "CC: $<" + @$(CXX) -c $(CXXELFFLAGS) $< -o $@ + +# This contains libstdc++ stubs to that you can build C++ code +# without actually having libstdc++ + +$(LIBSTDC_STUBS_LIB): + @$(MAKE) -C $(LIBSTDC_STUBS_DIR) TOPDIR=$(TOPDIR) + +# BIN1 and BIN2 link just like C code because they contain no +# static constructors. BIN1 is equivalent to a C hello world; +# BIN2 contains a class that implements hello world, but it is +# not statically initialized. + +$(BIN1): $(OBJS1) + @echo "LD: $<" + @$(LD) $(LDELFFLAGS) -o $@ $^ + +$(BIN2): $(OBJS2) + @echo "LD: $<" + @$(LD) $(LDELFFLAGS) -o $@ $^ + +# BIN3 is equivalent to BIN2 except that is uses static initializers + +ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y) +$(BIN3): $(OBJS3) + @echo "LD: $<" + @$(LD) $(LDELFFLAGS) -o $@ $^ +endif + +# BIN4 is similar to BIN3 except that it uses the streams code from libstdc++ +# +# NOTE: libstdc++ is not available for NuttX as of this writing +# +#$(BIN4): $(OBJS4) +# @echo "LD: $<" +# @$(LD) $(LDELFFLAGS) -o $@ $^ + +clean: + @rm -f $(ALL_BIN) *.o *~ .*.swp core + +install: $(ALL_BIN) + @install -D $(BIN1) $(ROMFS_DIR)/$(BIN1) + @install -D $(BIN2) $(ROMFS_DIR)/$(BIN2) +ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y) + @install -D $(BIN3) $(ROMFS_DIR)/$(BIN3) +endif +# @install -D $(BIN4) $(ROMFS_DIR)/$(BIN4) + + + + + + + diff --git a/apps/examples/elf/tests/helloxx/hello++1.cpp b/apps/examples/elf/tests/helloxx/hello++1.cpp new file mode 100644 index 000000000..9ab9d4ded --- /dev/null +++ b/apps/examples/elf/tests/helloxx/hello++1.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////// +// examples/elf/tests/helloxx/hello++1.c +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX nor the names of its contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// +// +// This is an trivial version of "Hello, World" program. It illustrates +// that we can build C programs using the C++ compiler. +// +// - Building a C++ program to use the C library +// - No class creation +// - NO Streams +// - NO Static constructor and destructors +// +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + printf("Hello, World!\n"); + return 0; +} diff --git a/apps/examples/elf/tests/helloxx/hello++2.cpp b/apps/examples/elf/tests/helloxx/hello++2.cpp new file mode 100644 index 000000000..f1268dda5 --- /dev/null +++ b/apps/examples/elf/tests/helloxx/hello++2.cpp @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////// +// examples/elf/tests/helloxx/hello++2.c +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX nor the names of its contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// +// +// This is an another trivial version of "Hello, World" design. It illustrates +// +// - Building a C++ program to use the C library +// - Basic class creation +// - NO Streams +// - NO Static constructor and destructors +// +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +///////////////////////////////////////////////////////////////////////////// +// Classes +///////////////////////////////////////////////////////////////////////////// + +class CThingSayer +{ + const char *szWhatToSay; +public: + CThingSayer(void) + { + printf("CThingSayer::CThingSayer: I am!\n"); + szWhatToSay = (const char*)NULL; + } + + ~CThingSayer(void) + { + printf("CThingSayer::~CThingSayer: I cease to be\n"); + if (szWhatToSay) + { + printf("CThingSayer::~CThingSayer: I will never say '%s' again\n", + szWhatToSay); + } + szWhatToSay = (const char*)NULL; + } + + void Initialize(const char *czSayThis) + { + printf("CThingSayer::Initialize: When told, I will say '%s'\n", + czSayThis); + szWhatToSay = czSayThis; + } + + void SayThing(void) + { + printf("CThingSayer::SayThing: I am now saying '%s'\n", szWhatToSay); + } +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + CThingSayer *MyThingSayer; + + printf("main: Started. Creating MyThingSayer\n"); + + // Create an instance of the CThingSayer class + // We should see the message from constructor, CThingSayer::CThingSayer(), + + MyThingSayer = new CThingSayer; + printf("main: Created MyThingSayer=0x%08lx\n", (long)MyThingSayer); + + // Tell MyThingSayer that "Hello, World!" is the string to be said + + printf("main: Calling MyThingSayer->Initialize\n");; + MyThingSayer->Initialize("Hello, World!"); + + // Tell MyThingSayer to say the thing we told it to say + + printf("main: Calling MyThingSayer->SayThing\n");; + MyThingSayer->SayThing(); + + // We should see the message from the destructor, + // CThingSayer::~CThingSayer(), AFTER we see the following + + printf("main: Destroying MyThingSayer\n"); + delete MyThingSayer; + + printf("main: Returning\n");; + return 0; +} diff --git a/apps/examples/elf/tests/helloxx/hello++3.cpp b/apps/examples/elf/tests/helloxx/hello++3.cpp new file mode 100644 index 000000000..6661a3fd1 --- /dev/null +++ b/apps/examples/elf/tests/helloxx/hello++3.cpp @@ -0,0 +1,132 @@ +///////////////////////////////////////////////////////////////////////////// +// examples/elf/tests/helloxx/hello++3.c +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX nor the names of its contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// +// +// This is an another trivial version of "Hello, World" design. It illustrates +// +// - Building a C++ program to use the C library and stdio +// - Basic class creation with virtual methods. +// - Static constructor and destructors (in main program only) +// - NO Streams +// +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include + +///////////////////////////////////////////////////////////////////////////// +// Classes +///////////////////////////////////////////////////////////////////////////// + +class CThingSayer +{ + const char *szWhatToSay; +public: + CThingSayer(void); + virtual ~CThingSayer(void); + virtual void Initialize(const char *czSayThis); + virtual void SayThing(void); +}; + +// A static instance of the CThingSayer class. This instance MUST +// be constructed by the system BEFORE the program is started at +// main() and must be destructed by the system AFTER the main() +// returns to the system + +static CThingSayer MyThingSayer; + +// These are implementations of the methods of the CThingSayer class + +CThingSayer::CThingSayer(void) +{ + printf("CThingSayer::CThingSayer: I am!\n"); + szWhatToSay = (const char*)NULL; +} + +CThingSayer::~CThingSayer(void) +{ + printf("CThingSayer::~CThingSayer: I cease to be\n"); + if (szWhatToSay) + { + printf("CThingSayer::~CThingSayer: I will never say '%s' again\n", + szWhatToSay); + } + szWhatToSay = (const char*)NULL; +} + +void CThingSayer::Initialize(const char *czSayThis) +{ + printf("CThingSayer::Initialize: When told, I will say '%s'\n", + czSayThis); + szWhatToSay = czSayThis; +} + +void CThingSayer::SayThing(void) +{ + printf("CThingSayer::SayThing: I am now saying '%s'\n", szWhatToSay); +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + // We should see the message from constructor, CThingSayer::CThingSayer(), + // BEFORE we see the following messages. That is proof that the + // C++ static initializer is working + + printf("main: Started. MyThingSayer should already exist\n"); + + // Tell MyThingSayer that "Hello, World!" is the string to be said + + printf("main: Calling MyThingSayer.Initialize\n");; + MyThingSayer.Initialize("Hello, World!"); + + // Tell MyThingSayer to say the thing we told it to say + + printf("main: Calling MyThingSayer.SayThing\n");; + MyThingSayer.SayThing(); + + // We are finished, return. We should see the message from the + // destructor, CThingSayer::~CThingSayer(), AFTER we see the following + // message. That is proof that the C++ static destructor logic + // is working + + printf("main: Returning. MyThingSayer should be destroyed\n");; + return 0; +} diff --git a/apps/examples/elf/tests/helloxx/hello++4.cpp b/apps/examples/elf/tests/helloxx/hello++4.cpp new file mode 100644 index 000000000..7db2564ed --- /dev/null +++ b/apps/examples/elf/tests/helloxx/hello++4.cpp @@ -0,0 +1,150 @@ +///////////////////////////////////////////////////////////////////////////// +// examples/elf/tests/helloxx/hello++4.c +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX nor the names of its contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// +// +// This is an excessively complex version of "Hello, World" design to +// illustrate some basic properties of C++: +// +// - Building a C++ program +// - Streams / statically linked libstdc++ +// - Static constructor and destructors (in main program only) +// +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include +#include + +#ifndef NULL +# define NULL ((void*)0L) +#endif + +///////////////////////////////////////////////////////////////////////////// +// Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace std; + +// A hello world sayer class + +class CThingSayer +{ + const char *szWhatToSay; +public: + CThingSayer(void); + virtual ~CThingSayer(void); + virtual void Initialize(const char *czSayThis); + virtual void SayThing(void); +}; + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +// A static instance of the CThingSayer class. This instance MUST +// be constructed by the system BEFORE the program is started at +// main() and must be destructed by the system AFTER the main() +// returns to the system + +static CThingSayer MyThingSayer; + +///////////////////////////////////////////////////////////////////////////// +// Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// These are implementations of the methods of the CThingSayer class + +CThingSayer::CThingSayer(void) +{ + cout << "CThingSayer::CThingSayer: I am!" << endl; + szWhatToSay = (const char*)NULL; +} + +CThingSayer::~CThingSayer(void) +{ + cout << "CThingSayer::~CThingSayer: I cease to be" << endl; + if (szWhatToSay) + { + cout << "CThingSayer::~CThingSayer: I will never say '" + << szWhatToSay << "' again" << endl; + } + szWhatToSay = (const char*)NULL; +} + +void CThingSayer::Initialize(const char *czSayThis) +{ + cout << "CThingSayer::Initialize: When told, I will say '" + << czSayThis << "'" << endl; + szWhatToSay = czSayThis; +} + +void CThingSayer::SayThing(void) +{ + cout << "CThingSayer::SayThing: I am now saying '" + << szWhatToSay << "'" << endl; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + // We should see the message from constructor, CThingSayer::CThingSayer(), + // BEFORE we see the following messages. That is proof that the + // C++ static initializer is working + + cout << "main: Started" << endl; + + // Tell MyThingSayer that "Hello, World!" is the string to be said + + cout << "main: Calling MyThingSayer.Initialize" << endl; + MyThingSayer.Initialize("Hello, World!"); + + // Tell MyThingSayer to say the thing we told it to say + + cout << "main: Calling MyThingSayer.SayThing" << endl; + MyThingSayer.SayThing(); + + // We are finished, return. We should see the message from the + // destructor, CThingSayer::~CThingSayer(), AFTER we see the following + // message. That is proof that the C++ static destructor logic + // is working + + cout << "main: Returning" << endl; + return 0; +} -- cgit v1.2.3