# This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # Makefile # common # common/classes.cc # common/classes.h # lib # lib/Makefile # lib/downcast.cc # prog # prog/Makefile # prog/dynamic_cast.1 # prog/dynamic_cast.cc # echo x - Makefile sed 's/^X//' >Makefile << 'b67911656ef5d18c4ae36cb6741b7965' XSUBDIR=lib prog X Xrun:: X /usr/bin/env LD_LIBRARY_PATH=${.OBJDIR}/lib:${LD_LIBRARY_PATH} ${.OBJDIR}/prog/dynamic_cast X X.include b67911656ef5d18c4ae36cb6741b7965 echo c - common mkdir -p common > /dev/null 2>&1 echo x - common/classes.cc sed 's/^X//' >common/classes.cc << 'a07ef8e0bbcd013b1ad299f7d8b2489a' X#include "classes.h" X Xint Parent::something(void) { return 1; } Xint Child::something(void) { return 2; } a07ef8e0bbcd013b1ad299f7d8b2489a echo x - common/classes.h sed 's/^X//' >common/classes.h << '8bd6b113f0957a684f12533972e2849f' Xclass Parent { X public: X virtual int something(void); X}; Xclass Child : public Parent { X public: X virtual int something(void); X}; 8bd6b113f0957a684f12533972e2849f echo c - lib mkdir -p lib > /dev/null 2>&1 echo x - lib/Makefile sed 's/^X//' >lib/Makefile << '94e18c7e8b5bab8a1215265cdb5ca1f4' XSRCDIR= ${.CURDIR}/../common X XSHLIB_MAJOR= 1 X X.PATH: ${SRCDIR} X XLIB= dynamic_cast X XSRCS+= \ X classes.cc \ X downcast.cc X XWARNS= 9 XCXXFLAGS+= -I${SRCDIR} X X.include 94e18c7e8b5bab8a1215265cdb5ca1f4 echo x - lib/downcast.cc sed 's/^X//' >lib/downcast.cc << '83e7bd6954b57f3f10f791ff49167079' X#include X X#if __cplusplus Xextern "C" int runsomething(Parent *ptr); Xextern "C" void *downcast(Parent *ptr); X#endif X Xint Xrunsomething(Parent *ptr) X{ X return ptr->something(); X} X Xvoid * Xdowncast(Parent *ptr) X{ X Child *n = dynamic_cast(ptr); X return n; X} 83e7bd6954b57f3f10f791ff49167079 echo c - prog mkdir -p prog > /dev/null 2>&1 echo x - prog/Makefile sed 's/^X//' >prog/Makefile << '10dda222a2d60d4d7795f25f4761aac9' XSRCDIR= ${.CURDIR}/../common X X.PATH: ${SRCDIR} X XPROG= dynamic_cast XPROG_CXX:= ${PROG} X XSRCS+= \ X classes.cc \ X dynamic_cast.cc X X XCFLAGS+= -I${SRCDIR} XCXXFLAGS+= -std=c++11 X XWARNS= 9 X X.include X XTARGET_OSNAME ?= BSD X.if ${TARGET_OSNAME} == "Linux" X_CCLINK= ${CXX} XLDADD += -ldl X.endif X 10dda222a2d60d4d7795f25f4761aac9 echo x - prog/dynamic_cast.1 sed 's/^X//' >prog/dynamic_cast.1 << '862ebc4528faab8809aa13cd743cdf1f' X.Dd July 20, 2015 X.Dt dynamic_cast 1 X.Os X.Sh NAME X.Nm dynamic_cast X.Nd Test C++ dynamic_cast feature of the runtime C++11 library X.Sh SYNOPSIS X.Nm X.Sh DESCRIPTION XThis utility tests how C++ X.Fn dynamic_cast Xcasting works across shared modules linked at run-time. X.Pp XDowncasting is an attempt to cast a pointer of the value of a base class Xto the value of a derived class, provided the runtime type information X(RTTI) is provided. The X.Fn dynamic_cast Xoperator fails if the object is not an intance of a derived class. X.Pp XIn this example downcasting is attempted in one module as well Xas via the library provided at run-time. X.Sh AUTHOR XMarcin Cieslak 862ebc4528faab8809aa13cd743cdf1f echo x - prog/dynamic_cast.cc sed 's/^X//' >prog/dynamic_cast.cc << 'fdbd0639903ecb20c6c82f358a55b0fc' X#include X#include X#include X X#include "classes.h" X Xstatic const char *libpath = "libdynamic_cast.so"; Xint Xmain() X{ X void *lib, *sym; X Parent obj1 = Parent(); X Child obj2 = Child(); X Parent *objptr1 = &obj1; X Parent *objptr2 = &obj2; X if ((lib = dlopen(libpath, RTLD_LAZY))) { X if ((sym = dlsym(lib, "runsomething"))) { X printf("Parent::something() = %d\n", (*(int(*)(Parent *))sym)(objptr1)); X printf("Child::something() = %d\n", (*(int(*)(Parent *))sym)(objptr2)); X } else { X fprintf(stderr, "dlsym(\"runsomething\"): %s\n", dlerror()); X return EX_SOFTWARE; X } X if ((sym = dlsym(lib, "downcast"))) { X printf("library dynamic_cast(Parent *) = %p\n", X (*(void *(*)(Parent *))sym)(objptr1)); X printf("library dynamic_cast(Child *) = %p\n", X (*(void *(*)(Parent *))sym)(objptr2)); X printf("local dynamic_cast(Parent *) = %p\n", X dynamic_cast(objptr1)); X printf("local dynamic_cast(Child *) = %p\n", X dynamic_cast(objptr2)); X } else { X fprintf(stderr, "dlsym(\"downcast\"): %s\n", dlerror()); X return EX_SOFTWARE; X } X return 0; X } else { X fprintf(stderr, "dlopen: %s\n", dlerror()); X return EX_SOFTWARE; X } X} fdbd0639903ecb20c6c82f358a55b0fc exit