diff options
Diffstat (limited to 'Examples/ruby/mark_function')
-rw-r--r-- | Examples/ruby/mark_function/Makefile | 19 | ||||
-rw-r--r-- | Examples/ruby/mark_function/example.cxx | 61 | ||||
-rw-r--r-- | Examples/ruby/mark_function/example.dsp | 154 | ||||
-rw-r--r-- | Examples/ruby/mark_function/example.h | 49 | ||||
-rw-r--r-- | Examples/ruby/mark_function/example.i | 37 | ||||
-rw-r--r-- | Examples/ruby/mark_function/runme.rb | 23 |
6 files changed, 343 insertions, 0 deletions
diff --git a/Examples/ruby/mark_function/Makefile b/Examples/ruby/mark_function/Makefile new file mode 100644 index 0000000..56c84c6 --- /dev/null +++ b/Examples/ruby/mark_function/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/mark_function/example.cxx b/Examples/ruby/mark_function/example.cxx new file mode 100644 index 0000000..504e8fc --- /dev/null +++ b/Examples/ruby/mark_function/example.cxx @@ -0,0 +1,61 @@ +#include "example.h" + +Animal::Animal(const char* name) : name_(name) +{ +} + +Animal::~Animal() +{ + name_ = "Destroyed"; +} + +/* Return the animal's name */ +const char* Animal::get_name() const +{ + return name_.c_str(); +} + +Zoo::Zoo() +{ +} + +Zoo::~Zoo() +{ + return; +} + +/* Create a new animal. */ +Animal* Zoo::create_animal(const char* name) +{ + return new Animal(name); +} + +/* Add a new animal to the zoo. */ +void Zoo::add_animal(Animal* animal) +{ + animals.push_back(animal); +} + +Animal* Zoo::remove_animal(size_t i) +{ + /* Note a production implementation should check + for out of range errors. */ + Animal* result = this->animals[i]; + IterType iter = this->animals.begin(); + std::advance(iter, i); + this->animals.erase(iter); + + return result; +} + +/* Return the number of animals in the zoo. */ +size_t Zoo::get_num_animals() const +{ + return animals.size(); +} + +/* Return a pointer to the ith animal */ +Animal* Zoo::get_animal(size_t i) const +{ + return animals[i]; +} diff --git a/Examples/ruby/mark_function/example.dsp b/Examples/ruby/mark_function/example.dsp new file mode 100644 index 0000000..2adab78 --- /dev/null +++ b/Examples/ruby/mark_function/example.dsp @@ -0,0 +1,154 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=example - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(RUBY_INCLUDE)" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(RUBY_LIB)" /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(RUBY_INCLUDE)" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(RUBY_LIB)" /nologo /dll /machine:I386 /out:"example.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "example - Win32 Debug"
+# Name "example - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\example.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\example_wrap.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\example.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\example.i
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo RUBY_INCLUDE: %RUBY_INCLUDE%
+ echo RUBY_LIB: %RUBY_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -ruby $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo RUBY_INCLUDE: %RUBY_INCLUDE%
+ echo RUBY_LIB: %RUBY_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -ruby $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/Examples/ruby/mark_function/example.h b/Examples/ruby/mark_function/example.h new file mode 100644 index 0000000..933bb36 --- /dev/null +++ b/Examples/ruby/mark_function/example.h @@ -0,0 +1,49 @@ +#ifndef _EXAMPLE_H_ +#define _EXAMPLE_H_ + +#include <vector> +#include <string> + +class Animal +{ +protected: + std::string name_; +public: + // Construct an animal with a name + Animal(const char* name); + + // Destruct an animal + ~Animal(); + + // Return the animal's name + const char* get_name() const; +}; + +class Zoo +{ +private: + typedef std::vector<Animal*> AnimalsType; + typedef AnimalsType::iterator IterType; +protected: + AnimalsType animals; +public: + Zoo(); + ~Zoo(); + + /* Create a new animal */ + static Animal* create_animal(const char* name); + + /* Add a new animal to the zoo */ + void add_animal(Animal* animal); + + /* Remove an animal from the zoo */ + Animal* remove_animal(size_t i); + + /* Return the number of animals in the zoo */ + size_t get_num_animals() const; + + /* Return a pointer to the ith animal */ + Animal* get_animal(size_t i) const; +}; + +#endif /*_EXAMPLE_H_*/ diff --git a/Examples/ruby/mark_function/example.i b/Examples/ruby/mark_function/example.i new file mode 100644 index 0000000..6380fa0 --- /dev/null +++ b/Examples/ruby/mark_function/example.i @@ -0,0 +1,37 @@ +%module example + +%{ +#include "example.h" +%} + +/* Tell SWIG that create_animal creates a new object */ +%newobject Zoo::create_animal; + +/* Keep track of mappings between C/C++ structs/classes + and Ruby objects so we can implement a mark function. */ +%trackobjects; + + +/* Specify the mark function */ +%markfunc Zoo "mark_Zoo"; + +%include "example.h" + +%header %{ + static void mark_Zoo(void* ptr) { + Zoo* zoo = (Zoo*) ptr; + + /* Loop over each object and tell the garbage collector + that we are holding a reference to them. */ + int count = zoo->get_num_animals(); + + for(int i = 0; i < count; ++i) { + Animal* animal = zoo->get_animal(i); + VALUE object = SWIG_RubyInstanceFor(animal); + + if (object != Qnil) { + rb_gc_mark(object); + } + } + } +%} diff --git a/Examples/ruby/mark_function/runme.rb b/Examples/ruby/mark_function/runme.rb new file mode 100644 index 0000000..6d84ee8 --- /dev/null +++ b/Examples/ruby/mark_function/runme.rb @@ -0,0 +1,23 @@ +require 'example' + +# create a zoo +zoo = Example::Zoo.new + +begin + # Add in an couple of animals + tiger1 = Example::Animal.new("tiger1") + zoo.add_animal(tiger1) + + # unset variables to force gc + tiger = nil +end + +GC.start + +# Now get the tiger again +tiger2 = zoo.get_animal(0) + +# Call a method to verify the animal is still valid and not gc'ed +if tiger2.get_name != "tiger1" + raise RuntimeError, "Wrong animal name" +end |