Author: eweitz Date: Wed Apr 30 04:30:03 2008 New Revision: 7
Added: trunk/rdnzl-cpp/CHANGELOG.txt (contents, props changed) trunk/rdnzl-cpp/RDNZL/ trunk/rdnzl-cpp/RDNZL.sln (contents, props changed) trunk/rdnzl-cpp/RDNZL/AssemblyInfo.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/DelegateAdapter.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/DelegateAdapter.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/DotNetContainer.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/DotNetContainer.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/DotNetReference.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/DotNetReference.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/Field.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/Field.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/InvocationResult.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/InvocationResult.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/InvokeConstructor.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/InvokeConstructor.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/InvokeMember.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/InvokeMember.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/Property.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/Property.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/RDNZL.vcproj (contents, props changed) trunk/rdnzl-cpp/RDNZL/Stdafx.cpp (contents, props changed) trunk/rdnzl-cpp/RDNZL/Stdafx.h (contents, props changed) trunk/rdnzl-cpp/RDNZL/rdnzl.def (contents, props changed) trunk/rdnzl-cpp/README.txt (contents, props changed) Log: Import 0.7.1
Added: trunk/rdnzl-cpp/CHANGELOG.txt ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/CHANGELOG.txt Wed Apr 30 04:30:03 2008 @@ -0,0 +1,52 @@ +Version 0.7.1 +2008-02-19 +Fixed nullptr check in InvokeMember.cpp (thanks to Per Arild Fiskum and Iver Odin Kvello) + +Version 0.7.0 +2008-02-14 +Fixed return value of the generated delegate adapters (thanks to Iver Odin Kvello and Michael Mills) +Moved to Visual Studio 2005 (thanks to Michael Goffioul and Matthew D Swank) + +Version 0.6.0 +2007-05-18 +Added copyDotNetContainer (patch from Iver Odin Kvello) +Added setDotNetContainerTypeFromContainer (patch from Iver Odin Kvello) + +Version 0.5.2 +2006-09-27 +Only call back into Lisp if callback pointers aren't NULL (suggested by Michael Goffioul) + +Version 0.5.1 +2006-09-15 +Set apartment state to STA (thanks to Michael Goffioul) + +Version 0.5.0 +2006-01-13 +Fix mechanism which releases delegate adapters (thanks to Dominic Robinson) + +Version 0.4.1 +2005-11-21 +Added missing constructor for single float (caught by Andrew Wolven) + +Version 0.4.0 +2005-01-03 +Added interface functions for "direct calls" +Added ChangeType code to setDotNetContainerTypeFromString + +Version 0.3.1 +2004-12-23 +Fixed typo in declaration of makeDotNetContainerFromFloat + +Version 0.3.0 +2004-12-23 +Added better support for System.Single (thanks to Vasilis Margioulas) + +Version 0.2.0 +2004-12-17 +Added support for pass-by-reference handling +Correct linker settings for release configuration +Some cleanup in routines that throw errors + +Version 0.1.0 +2004-12-16 +Initial public release
Added: trunk/rdnzl-cpp/RDNZL.sln ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL.sln Wed Apr 30 04:30:03 2008 @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RDNZL", "RDNZL\RDNZL.vcproj", "{08A74849-5B79-4488-8F41-731C19FE3A13}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {08A74849-5B79-4488-8F41-731C19FE3A13}.Debug|Win32.ActiveCfg = Release|Win32 + {08A74849-5B79-4488-8F41-731C19FE3A13}.Debug|Win32.Build.0 = Release|Win32 + {08A74849-5B79-4488-8F41-731C19FE3A13}.Release|Win32.ActiveCfg = Release|Win32 + {08A74849-5B79-4488-8F41-731C19FE3A13}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal
Added: trunk/rdnzl-cpp/RDNZL/AssemblyInfo.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/AssemblyInfo.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,34 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/AssemblyInfo.cpp,v 1.11 2008/02/14 07:34:30 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" + +[assembly:AssemblyTitleAttribute("RDNZL")]; +[assembly:AssemblyDescriptionAttribute("DLL to be used by the RDNZL library which interfaces Common Lisp to .NET")]; +[assembly:AssemblyCopyrightAttribute("(c) Dr. Edmund Weitz 2004")]; +[assembly:AssemblyVersionAttribute("0.1.0.0")];
Added: trunk/rdnzl-cpp/RDNZL/DelegateAdapter.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DelegateAdapter.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,66 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DelegateAdapter.cpp,v 1.20 2008/02/14 11:54:02 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "DelegateAdapter.h" + +// the destructor notifies Lisp that this instance is no longer used - +// might be called from a "foreign" thread, see docs +DelegateAdapter::~DelegateAdapter() { + if (release != NULL) { + release(indexIntoLisp); + } +} + +// initialize the instance with an index that points back to the +// actual Lisp closure (via a Lisp hash table) +void DelegateAdapter::init(int index) { + indexIntoLisp = index; +} + +// this does all the work (by calling the Lisp closure) after the +// wrapper (build at runtime from Lisp via reflection) has marshalled +// the delegate's arguments into an array of objects +Object^ DelegateAdapter::invoke (cli::array<Object^> ^args) { + if (callback != NULL) { + void *ptr = callback(indexIntoLisp, new DotNetContainer(args)); + // the Lisp closure is supposed to return a pointer to a + // DotNetContainer which we marshall back into the underlying object + return static_cast<DotNetContainer *>(ptr)->getContainerObject(); + } else { + // a dummy object... + return gcnew Object(); + } +} + +// this static function is called once in the beginning to initialize +// the function pointers pointing to two Lisp callbacks +void setFunctionPointers(void *(*callback_fp)(int, void *), void (*release_fp)(int)) { + DelegateAdapter::callback = callback_fp; + DelegateAdapter::release = release_fp; +}
Added: trunk/rdnzl-cpp/RDNZL/DelegateAdapter.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DelegateAdapter.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,48 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DelegateAdapter.h,v 1.13 2008/02/14 07:34:30 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "DotNetContainer.h" + +public ref class DelegateAdapter { + public: + ~DelegateAdapter(); + void init(int index); + Object ^invoke (cli::array<Object^> ^args); + static void *(*callback)(int, void *); + static void (*release)(int); + private: + // the index into the Lisp hash table which holds the closures - + // should be a 64-bit integer in the future + int indexIntoLisp; +}; + +extern "C" { + __declspec(dllexport) void setFunctionPointers(void *(*callback_fp)(int, void *), void (*release_fp)(int)); +}
Added: trunk/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,137 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.cpp,v 1.11 2008/02/14 11:54:02 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "DelegateAdapterBuilder.h" + +// always returns the same module builder which is cached +ModuleBuilder ^DelegateAdapterBuilder::getModuleBuilder() { + if (moduleBuilder != nullptr) + return moduleBuilder; + + // if not cached already create it once + AssemblyName ^assemblyName = gcnew AssemblyName(); + assemblyName->Name = privateAssemblyName; + assemblyName->Version = gcnew Version("1.0.0.0"); + + AppDomain ^appDomain = Thread::GetDomain(); + AssemblyBuilder ^assemblyBuilder = appDomain->DefineDynamicAssembly( + assemblyName, + AssemblyBuilderAccess::Run + ); + + moduleBuilder = assemblyBuilder->DefineDynamicModule(privateAssemblyName); + + return moduleBuilder; +} + +// creates a constructor for our new type +void DelegateAdapterBuilder::generateConstructor(ILGenerator ^ilGenerator) { + // the simplest one possible - no arguments, just call the + // constructor of the base type + ilGenerator->Emit(OpCodes::Ldarg_0); + ilGenerator->Emit(OpCodes::Call, DelegateAdapter::typeid->GetConstructor(gcnew cli::array<Type^>(0))); + ilGenerator->Emit(OpCodes::Ret); +} + +// creates the "InvokeClosure" method which calls DelegateAdapter's +// "invoke" +void DelegateAdapterBuilder::generateInvokeMethod(ILGenerator ^ilGenerator, Type ^returnType, cli::array<Type^> ^argTypes) { + int nargs = argTypes->Length; + + // create a System.Object array of the same length as argTypes + ilGenerator->DeclareLocal(cli::array<Object^>::typeid /*__typeof(Object*[])*/); + ilGenerator->Emit(OpCodes::Ldc_I4, nargs); + ilGenerator->Emit(OpCodes::Newarr, System::Object::typeid); + ilGenerator->Emit(OpCodes::Stloc_0); + + // store method arguments in this array + for (int i = 0; i < nargs; i++) { + ilGenerator->Emit(OpCodes::Ldloc_0); + ilGenerator->Emit(OpCodes::Ldc_I4, i); + ilGenerator->Emit(OpCodes::Ldarg, i + 1); + + Type ^argType = argTypes[i]; + if (argType->IsValueType) + ilGenerator->Emit(OpCodes::Box, argType); + ilGenerator->Emit(OpCodes::Stelem_Ref); + } + + // call "invoke" with this array + ilGenerator->Emit(OpCodes::Ldarg_0); + ilGenerator->Emit(OpCodes::Ldloc_0); + ilGenerator->Emit(OpCodes::Call,DelegateAdapter::typeid->GetMethod("invoke")); + + // handle return value of "invoke" + if (returnType->Equals(Void::typeid)) + ilGenerator->Emit(OpCodes::Pop); + else if (returnType->IsValueType) + ilGenerator->Emit(OpCodes::Unbox_Any, returnType); + + ilGenerator->Emit(OpCodes::Ret); +} + +// build a new type which derives from DelegateAdapter and is +// responsible for Lisp callbacks with a signature as described by +// returnType and argTypes +Type ^DelegateAdapterBuilder::buildDelegateType (String ^typeName, Type ^returnType, cli::array<Type^> ^argTypes) { + TypeBuilder ^typeBuilder = getModuleBuilder()->DefineType( + String::Concat(privateAssemblyName, ".", typeName), + TypeAttributes::Public, + DelegateAdapter::typeid + ); + + generateConstructor(typeBuilder->DefineConstructor( + MethodAttributes::Public, + CallingConventions::Standard, + gcnew cli::array<Type^>(0) + )->GetILGenerator()); + generateInvokeMethod( + typeBuilder->DefineMethod( + "InvokeClosure", + MethodAttributes::Public, + returnType, + argTypes + )->GetILGenerator(), + returnType, + argTypes + ); + + return typeBuilder->CreateType(); +} + +// the C interface +__declspec(dllexport) void *buildDelegateType(const __wchar_t *typeName, void *returnType, void *argTypes) { + Type ^newType = DelegateAdapterBuilder::buildDelegateType( + gcnew String(typeName), + safe_cast<Type ^>(static_cast<DotNetContainer *>(returnType)->getContainerObject()), + safe_cast<cli::array<Type^> ^>(static_cast<DotNetContainer *>(argTypes)->getContainerObject()) + ); + + return new DotNetContainer(newType); +}
Added: trunk/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,49 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DelegateAdapterBuilder.h,v 1.7 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "stdafx.h" +#include "DelegateAdapter.h" + +public ref class DelegateAdapterBuilder { + public: + static Type ^buildDelegateType (String ^typeName, Type ^returnType, cli::array<Type^> ^argTypes); + private: + static String ^privateAssemblyName = "RDNZLPrivateAssembly"; + // cache for ModuleBuilder object + static ModuleBuilder ^moduleBuilder = nullptr; + + static ModuleBuilder ^getModuleBuilder(); + static void generateConstructor(ILGenerator ^ilGenerator); + static void generateInvokeMethod(ILGenerator ^ilGenerator, Type ^returnType, cli::array<Type^> ^argTypes); +}; + +extern "C" { + __declspec(dllexport) void *buildDelegateType(const __wchar_t *typeName, void *returnType, void *argTypes); +}
Added: trunk/rdnzl-cpp/RDNZL/DotNetContainer.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DotNetContainer.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,246 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DotNetContainer.cpp,v 1.26 2008/02/14 12:13:04 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "DotNetContainer.h" + +// helper function for constructors - initialize both object and type +// slot, with NULL DotNetReference if necessary +void DotNetContainer::init(Object ^o, Type ^t) { + object = (o != nullptr) ? new DotNetReference(o) : new DotNetReference(); + type = (t != nullptr) ? new DotNetReference(t) : new DotNetReference(); +} + +// another helper function - calls init above +void DotNetContainer::init(Object ^o) { + if (o == nullptr) { + init(nullptr, nullptr); + } else { + // if type isn't explicitely provided, derive it from the object + init(o, o->GetType()); + } +} + +// constructor if type is explicitely set +DotNetContainer::DotNetContainer(Object ^o, Type ^t) { + init(o, t); +} + +// standard constructor +DotNetContainer::DotNetContainer(Object ^o) { + init(o); +} + +// the following five constructors box values types +DotNetContainer::DotNetContainer(bool b) { + init(b); +} + +DotNetContainer::DotNetContainer(__int32 n) { + init(n); +} + +DotNetContainer::DotNetContainer(__int64 n) { + init(n); +} + +DotNetContainer::DotNetContainer(float f) { + init(f); +} + +DotNetContainer::DotNetContainer(double d) { + init(d); +} + +DotNetContainer::DotNetContainer(__wchar_t c) { + init(c); +} + +// this constructor converts a C string into a .NET string +DotNetContainer::DotNetContainer(const __wchar_t *s) { + init(gcnew String(s)); +} + +// whether the stored object is NULL +bool DotNetContainer::isNull() { + return (object->getObject() == nullptr); +} + +Object ^DotNetContainer::getContainerObject() { + return object->getObject(); +} + +Type ^DotNetContainer::getContainerType() { + return safe_cast<Type ^>(type->getObject()); +} + +// change the value of the object slot +void DotNetContainer::setContainerObject(Object ^o) { + object = new DotNetReference(o); +} + +// change the value of the type slot (see CAST in Lisp code) +void DotNetContainer::setContainerType(Type ^t) { + type = new DotNetReference(t); +} + +DotNetContainer::~DotNetContainer() { + if (object) { + delete object; + } + if (type) { + delete type; + } +} + +// make a passed-by-reference type out of the container's type (if it +// isn't one already) +void DotNetContainer::refContainerType() { + Type ^t = safe_cast<Type ^>(type->getObject()); + if (!t->IsByRef) + type = new DotNetReference(t->Assembly->GetType(String::Concat(t->FullName, "&"))); +} + +// set the container's type to be its underlying type if it was passed +// by reference +void DotNetContainer::unrefContainerType() { + Type ^t = safe_cast<Type ^>(type->getObject()); + if (t->IsByRef) { + type = new DotNetReference(t->GetElementType()); + } +} + +// most of the functions below export the public interface of the +// DotNetContainer class to C + +__declspec(dllexport) bool DotNetContainerIsNull(void *ptr) { + return static_cast<DotNetContainer *>(ptr)->isNull(); +} + +// make a copy of an existing DotNetContainer +__declspec(dllexport) void *copyDotNetContainer(void *ptr) { + DotNetContainer* original = static_cast<DotNetContainer *> (ptr); + return new DotNetContainer(original->getContainerObject(), original->getContainerType()); +} + +// create a "placeholder" (NULL) container which only has a type +__declspec(dllexport) void *makeTypedNullDotNetContainer(const __wchar_t *type) { + return new DotNetContainer(nullptr, Type::GetType(gcnew String(type))); +} + +// create a container representing a type (obtained from its name) +__declspec(dllexport) void *makeTypeFromName(const __wchar_t *type) { + return new DotNetContainer(Type::GetType(gcnew String(type)), Type::typeid); +} + +__declspec(dllexport) void *makeDotNetContainerFromBoolean(bool b) { + return new DotNetContainer(b); +} + +__declspec(dllexport) void *makeDotNetContainerFromInt(int n) { + return new DotNetContainer(n); +} + +__declspec(dllexport) void *makeDotNetContainerFromLong(const __wchar_t *s) { + return new DotNetContainer(Int64::Parse(gcnew String(s))); +} + +__declspec(dllexport) void *makeDotNetContainerFromFloat(float d) { + return new DotNetContainer(d); +} + +__declspec(dllexport) void *makeDotNetContainerFromDouble(double d) { + return new DotNetContainer(d); +} + +__declspec(dllexport) void *makeDotNetContainerFromString(const __wchar_t *s) { + return new DotNetContainer(s); +} + +__declspec(dllexport) void *makeDotNetContainerFromChar(__wchar_t c) { + return new DotNetContainer(c); +} + +// we need to know the length to allocate storage on the Lisp side +__declspec(dllexport) int getDotNetContainerTypeStringLength(void *ptr) { + return static_cast<DotNetContainer *>(ptr)->getContainerType()->FullName->Length; +} + +// temporarily disable warnings here as we know that the destination is large enough +#pragma warning(disable:4996) +__declspec(dllexport) void getDotNetContainerTypeAsString(void *ptr, __wchar_t *s) { + cli::pin_ptr<const __wchar_t> temp = PtrToStringChars(static_cast<DotNetContainer *>(ptr)->getContainerType()->FullName); + wcscpy(s, temp); + #pragma warning(default:4996) +} + +// we need to know the length to allocate storage on the Lisp side +__declspec(dllexport) int getDotNetContainerObjectStringLength(void *ptr) { + return static_cast<DotNetContainer *>(ptr)->getContainerObject()->ToString()->Length; +} + +#pragma warning(disable:4996) +__declspec(dllexport) void getDotNetContainerObjectAsString(void *ptr, __wchar_t *s) { + cli::pin_ptr<const __wchar_t> temp = PtrToStringChars(static_cast<DotNetContainer *>(ptr)->getContainerObject()->ToString()); + wcscpy(s, temp); + #pragma warning(disable:4996) +} + +__declspec(dllexport) void refDotNetContainerType(void *ptr) { + static_cast<DotNetContainer *>(ptr)->refContainerType(); +} + +__declspec(dllexport) void unrefDotNetContainerType(void *ptr) { + static_cast<DotNetContainer *>(ptr)->unrefContainerType(); +} + +// "unboxing" + +__declspec(dllexport) __wchar_t getDotNetContainerCharValue(void *ptr) { + return *safe_cast<System::Char ^>(static_cast<DotNetContainer *>(ptr)->getContainerObject()); +} + +__declspec(dllexport) int getDotNetContainerIntValue(void *ptr) { + return *safe_cast<System::Int32 ^>(static_cast<DotNetContainer *>(ptr)->getContainerObject()); +} + +__declspec(dllexport) bool getDotNetContainerBooleanValue(void *ptr) { + return *safe_cast<System::Boolean ^>(static_cast<DotNetContainer *>(ptr)->getContainerObject()); +} + +__declspec(dllexport) double getDotNetContainerDoubleValue(void *ptr) { + return *safe_cast<System::Double ^>(static_cast<DotNetContainer *>(ptr)->getContainerObject()); +} + +__declspec(dllexport) float getDotNetContainerSingleValue(void *ptr) { + return *safe_cast<System::Single ^>(static_cast<DotNetContainer *>(ptr)->getContainerObject()); +} + +__declspec(dllexport) void freeDotNetContainer(void *ptr) { + delete static_cast<DotNetContainer *>(ptr); +}
Added: trunk/rdnzl-cpp/RDNZL/DotNetContainer.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DotNetContainer.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,91 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DotNetContainer.h,v 1.21 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "DotNetReference.h" +#include "DelegateAdapter.h" + +class DotNetContainer { + public: + DotNetContainer(Object ^o, Type ^t); + DotNetContainer(Object ^o); + DotNetContainer(bool b); + DotNetContainer(__int32 n); + DotNetContainer(__int64 n); + DotNetContainer(float f); + DotNetContainer(double d); + DotNetContainer(__wchar_t c); + DotNetContainer(const __wchar_t *s); + ~DotNetContainer(); + + bool isNull(); + Object ^getContainerObject(); + Type ^getContainerType(); + void setContainerObject(Object ^o); + void setContainerType(Type ^t); + void refContainerType(); + void unrefContainerType(); + private: + // the actual object + DotNetReference* object; + // the type of this object as seen from RDNZL + DotNetReference* type; + + void init(Object ^o, Type ^t); + void init(Object ^o); +}; + +extern "C" { + __declspec(dllexport) void *makeTypeFromName(const __wchar_t *type); + __declspec(dllexport) void *makeTypedNullDotNetContainer(const __wchar_t *type); + __declspec(dllexport) void *makeDotNetContainerFromBoolean(bool b); + __declspec(dllexport) void *makeDotNetContainerFromInt(int n); + __declspec(dllexport) void *makeDotNetContainerFromLong(const __wchar_t *s); + __declspec(dllexport) void *makeDotNetContainerFromFloat(float d); + __declspec(dllexport) void *makeDotNetContainerFromDouble(double d); + __declspec(dllexport) void *makeDotNetContainerFromChar(__wchar_t c); + __declspec(dllexport) void *makeDotNetContainerFromString(const __wchar_t *s); + __declspec(dllexport) bool DotNetContainerIsNull(void *ptr); + __declspec(dllexport) int getDotNetContainerTypeStringLength(void *ptr); + __declspec(dllexport) void getDotNetContainerTypeAsString(void *ptr, __wchar_t *s); + __declspec(dllexport) int getDotNetContainerObjectStringLength(void *ptr); + __declspec(dllexport) void getDotNetContainerObjectAsString(void *ptr, __wchar_t *s); + __declspec(dllexport) int getDotNetContainerIntValue(void *ptr); + __declspec(dllexport) __wchar_t getDotNetContainerCharValue(void *ptr); + __declspec(dllexport) bool getDotNetContainerBooleanValue(void *ptr); + __declspec(dllexport) double getDotNetContainerDoubleValue(void *ptr); + __declspec(dllexport) float getDotNetContainerSingleValue(void *ptr); + __declspec(dllexport) void refDotNetContainerType(void *ptr); + __declspec(dllexport) void unrefDotNetContainerType(void *ptr); + __declspec(dllexport) void freeDotNetContainer(void *ptr); + __declspec(dllexport) void *copyDotNetContainer(void *ptr); + // function definition is in InvocationResult.cpp + __declspec(dllexport) void *setDotNetContainerTypeFromString(const __wchar_t *type, void *ptr); + __declspec(dllexport) void *setDotNetContainerTypeFromContainer(void *type, void *ptr); +}
Added: trunk/rdnzl-cpp/RDNZL/DotNetReference.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DotNetReference.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,54 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DotNetReference.cpp,v 1.9 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "DotNetReference.h" + +// if constructor is called with no arguments act as NULL object +DotNetReference::DotNetReference() : ptr(0) {} + +// normal constructor +DotNetReference::DotNetReference(Object ^o) { + // acquire pointer to object so it can't be reclaimed by the .NET + // garbage collector until explicitely freed + ptr = ((IntPtr) GCHandle::Alloc(o)).ToPointer(); +} + +// destructor +DotNetReference::~DotNetReference() { + if (ptr) { + // give up pointer so garbage collector regains control + static_cast<GCHandle>((IntPtr)ptr).Free(); + } +} + +Object ^DotNetReference::getObject() { + // return the object the instance was initialized with + return ptr ? safe_cast<Object^>(static_cast<GCHandle>((IntPtr)ptr).Target) : nullptr; +} +
Added: trunk/rdnzl-cpp/RDNZL/DotNetReference.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/DotNetReference.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,40 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/DotNetReference.h,v 1.8 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +class DotNetReference { + public: + DotNetReference(); + DotNetReference(Object ^o); + ~DotNetReference(); + + Object ^getObject(); + private: + void *ptr; +};
Added: trunk/rdnzl-cpp/RDNZL/Field.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/Field.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,149 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/Field.cpp,v 1.16 2008/02/14 11:54:02 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "Field.h" + +// provide informative message about which field wasn't found +void Field::throwFieldNotFoundError(Type ^type, const __wchar_t *fieldName, BindingFlags bindingAttr) { + throw gcnew Exception(String::Concat( + (int)(BindingFlags::Static & bindingAttr) ? "Static field not found: " : "Instance field not found: ", + type->FullName, + "->", + gcnew String(fieldName) + )); +} + +// helper function to get values of static and instance fields +void *Field::getFieldValue(Object ^o, Type ^t, const __wchar_t *fieldName, BindingFlags bindingAttr) { + try { + // find field by name and binding attributes + FieldInfo ^fi = t->GetField(gcnew String(fieldName), bindingAttr); + + if (fi == nullptr) + throwFieldNotFoundError(t, fieldName, bindingAttr); + + return new InvocationResult(fi->GetValue(o), fi->FieldType); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to get values of static and instance fields +void *Field::getFieldValueDirectly(void *fieldInfo, Object ^o) { + try { + FieldInfo ^fi = safe_cast<FieldInfo ^>(static_cast<DotNetContainer *>(fieldInfo)->getContainerObject()); + return new InvocationResult(fi->GetValue(o), fi->FieldType); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to set values of static and instance fields +void *Field::setFieldValue(Object ^o, Type ^t, const __wchar_t *fieldName, Object ^newValue, BindingFlags bindingAttr) { + try { + // find field by name and binding attributes + FieldInfo ^fi = t->GetField(gcnew String(fieldName), bindingAttr); + + if (fi == nullptr) + throwFieldNotFoundError(t, fieldName, bindingAttr); + + fi->SetValue(o, newValue); + return new InvocationResult(); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to set values of static and instance fields +void *Field::setFieldValueDirectly(void *fieldInfo, Object ^o, void *newValue) { + try { + FieldInfo ^fi = safe_cast<FieldInfo ^>(static_cast<DotNetContainer *>(fieldInfo)->getContainerObject()); + + fi->SetValue(o, static_cast<DotNetContainer *>(newValue)->getContainerObject()); + return new InvocationResult(); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// below void pointers always point to DotNetContainer objects + +__declspec(dllexport) void *getInstanceFieldValue(const __wchar_t *fieldName, void *target) { + DotNetContainer *container = static_cast<DotNetContainer *>(target); + Type ^t = container->getContainerType(); + Object ^o = container->getContainerObject(); + return Field::getFieldValue(o, t, fieldName, static_cast<BindingFlags>(BindingFlags::Instance | BindingFlags::Public)); +} + +__declspec(dllexport) void *getStaticFieldValue(const __wchar_t *fieldName, void *type) { + Type ^t = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + return Field::getFieldValue(nullptr, t, fieldName, static_cast<BindingFlags>(BindingFlags::Static | BindingFlags::Public)); +} + +__declspec(dllexport) void *setInstanceFieldValue(const __wchar_t *fieldName, void *target, void *newValue) { + DotNetContainer *container = static_cast<DotNetContainer *>(target); + Type ^t = container->getContainerType(); + Object ^o = container->getContainerObject(); + return Field::setFieldValue(o, t, fieldName, + static_cast<DotNetContainer *>(newValue)->getContainerObject(), + safe_cast<BindingFlags>(BindingFlags::Instance | BindingFlags::Public)); +} + +__declspec(dllexport) void *setStaticFieldValue(const __wchar_t *fieldName, void *type, void *newValue) { + Type ^t = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + return Field::setFieldValue(nullptr, t, fieldName, + static_cast<DotNetContainer *>(newValue)->getContainerObject(), + safe_cast<BindingFlags>(BindingFlags::Static | BindingFlags::Public)); +} + +__declspec(dllexport) void *getInstanceFieldValueDirectly(void *fieldInfo, void *target) { + Object ^o = static_cast<DotNetContainer *>(target)->getContainerObject(); + return Field::getFieldValueDirectly(fieldInfo, o); +} + +__declspec(dllexport) void *getStaticFieldValueDirectly(void *fieldInfo) { + return Field::getFieldValueDirectly(fieldInfo, nullptr); +} + +__declspec(dllexport) void *setInstanceFieldValueDirectly(void *fieldInfo, void *target, void *newValue) { + Object ^o = static_cast<DotNetContainer *>(target)->getContainerObject(); + return Field::setFieldValueDirectly(fieldInfo, o, newValue); +} + +__declspec(dllexport) void *setStaticFieldValueDirectly(void *fieldInfo, void *newValue) { + return Field::setFieldValueDirectly(fieldInfo, nullptr, newValue); +}
Added: trunk/rdnzl-cpp/RDNZL/Field.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/Field.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,52 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/Field.h,v 1.12 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "InvocationResult.h" + +public ref class Field { + public: + static void *getFieldValue(Object ^o, Type ^t, const __wchar_t *fieldName, BindingFlags bindingAttr); + static void *getFieldValueDirectly(void *fieldInfo, Object ^o); + static void *setFieldValue(Object ^o, Type ^t, const __wchar_t *fieldName, Object ^newValue, BindingFlags bindingAttr); + static void *setFieldValueDirectly(void *fieldInfo, Object ^o, void *newValue); + private: + static void throwFieldNotFoundError(Type ^type, const __wchar_t *fieldName, BindingFlags bindingAttr); +}; + +extern "C" { + __declspec(dllexport) void *getInstanceFieldValue(const __wchar_t *fieldName, void *target); + __declspec(dllexport) void *getStaticFieldValue(const __wchar_t *fieldName, void *type); + __declspec(dllexport) void *setInstanceFieldValue(const __wchar_t *fieldName, void *target, void *newValue); + __declspec(dllexport) void *setStaticFieldValue(const __wchar_t *fieldName, void *type, void *newValue); + __declspec(dllexport) void *getInstanceFieldValueDirectly(void *fieldInfo, void *target); + __declspec(dllexport) void *getStaticFieldValueDirectly(void *fieldInfo); + __declspec(dllexport) void *setInstanceFieldValueDirectly(void *fieldInfo, void *target, void *newValue); + __declspec(dllexport) void *setStaticFieldValueDirectly(void *fieldInfo, void *newValue); +}
Added: trunk/rdnzl-cpp/RDNZL/InvocationResult.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/InvocationResult.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,114 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/InvocationResult.cpp,v 1.14 2008/02/14 07:43:41 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "InvocationResult.h" + +// constructor for "void" results +InvocationResult::InvocationResult() : isVoid_(true), isException_(false), result(0) {} + +// standard constructor +InvocationResult::InvocationResult(Object ^o, bool excp) : + isVoid_(false), isException_(excp), result(new DotNetContainer(o)) {} + +// constructor for results which are explicitely typed +InvocationResult::InvocationResult(Object ^o, Type ^t, bool excp) : + isVoid_(false), isException_(excp), result(new DotNetContainer(o, t)) {} + +bool InvocationResult::isVoid() { + return isVoid_; +} + +bool InvocationResult::isException() { + return isException_; +} + +DotNetContainer *InvocationResult::getResult() { + return result; +} + +__declspec(dllexport) bool InvocationResultIsVoid(void *ptr) { + return static_cast<InvocationResult *>(ptr)->isVoid(); +} + +__declspec(dllexport) bool InvocationResultIsException(void *ptr) { + return static_cast<InvocationResult *>(ptr)->isException(); +} + +__declspec(dllexport) void *getDotNetContainerFromInvocationResult(void *ptr) { + // this returns a NULL pointer if the result is void + return static_cast<InvocationResult *>(ptr)->getResult(); +} + +__declspec(dllexport) void freeInvocationResult(void *ptr) { + delete static_cast<InvocationResult *>(ptr); +} + +// helper function for setDotNetContainerTypeFromString and setDotNetContainerTypeFromContainer. +void *setDotNetContainerType(Type ^newType, void *ptr) { + try { + DotNetContainer *container = static_cast<DotNetContainer *>(ptr); + Type ^oldType = container->getContainerType(); + + if (oldType->IsAssignableFrom(newType)) { + container->setContainerType(newType); + } else { + Object ^newObject = Convert::ChangeType(container->getContainerObject(), newType); + container->setContainerObject(newObject); + container->setContainerType(newType); + } + // return void result + return new InvocationResult(); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// this should actually be in DotNetContainer.cpp but couldn't be defined there + +// if possible, change the type of the DotNetContainer given the string name of a type that will be found in the Load context. +__declspec(dllexport) void *setDotNetContainerTypeFromString(const __wchar_t *type, void *ptr) { + try { + // throw an exception if something happens + Type ^newType = Type::GetType(gcnew String(type), true); + return setDotNetContainerType(newType, ptr); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// change the type of the DotNetContainer, if possible, given a Type object. +__declspec(dllexport) void *setDotNetContainerTypeFromContainer(void *type, void *ptr) { + try { + // throw an exception if something happens + Type ^newType = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + return setDotNetContainerType(newType, ptr); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} \ No newline at end of file
Added: trunk/rdnzl-cpp/RDNZL/InvocationResult.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/InvocationResult.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,57 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/InvocationResult.h,v 1.10 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "DotNetContainer.h" + +class InvocationResult { + public: + InvocationResult(); + InvocationResult(Object ^o, bool excp = false); + InvocationResult(Object ^o, Type ^t, bool excp = false); + + bool isVoid(); + bool isException(); + DotNetContainer *getResult(); + private: + // whether the object represents the "result" of a method which + // doesn't return anything + bool isVoid_; + // whether an exception occured + bool isException_; + // the actual result, if there was one + DotNetContainer *result; +}; + +extern "C" { + __declspec(dllexport) bool InvocationResultIsVoid(void *ptr); + __declspec(dllexport) bool InvocationResultIsException(void *ptr); + __declspec(dllexport) void *getDotNetContainerFromInvocationResult(void *ptr); + __declspec(dllexport) void freeInvocationResult(void *ptr); +}
Added: trunk/rdnzl-cpp/RDNZL/InvokeConstructor.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/InvokeConstructor.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,49 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/InvokeConstructor.cpp,v 1.11 2008/02/14 11:54:03 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "InvokeConstructor.h" + +// invoke the constructor of the specified type and signature, the +// void pointers are pointers to DotNetContainer objects +__declspec(dllexport) void* invokeConstructor(void *type, int nargs, void *args[]) { + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs); + for (int i = 0; i < nargs; i++) { + realArgs[i] = static_cast<DotNetContainer *>(args[i])->getContainerObject(); + } + + try { + Type ^t = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + Object ^newInstance = Activator::CreateInstance(t, realArgs); + return new InvocationResult(newInstance); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +}
Added: trunk/rdnzl-cpp/RDNZL/InvokeConstructor.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/InvokeConstructor.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,35 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/InvokeConstructor.h,v 1.8 2008/02/14 07:34:31 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "InvocationResult.h" + +extern "C" { + __declspec(dllexport) void* invokeConstructor(void *type, int nargs, void *args[]); +}
Added: trunk/rdnzl-cpp/RDNZL/InvokeMember.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/InvokeMember.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,200 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/InvokeMember.cpp,v 1.22 2008/02/19 18:40:54 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "InvokeMember.h" + +// helper function for findMethod - recursively descends into +// all interfaces +MethodInfo^ InvokeMember::findInterfaceMethod(cli::array<Type^> ^interfaces, const __wchar_t *methodName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr) { + MethodInfo ^mi = nullptr; + + for (int i = 0; i < interfaces->Length && !mi; i++) { + mi = interfaces[i]->GetMethod(gcnew String(methodName), bindingAttr, nullptr, argTypes, nullptr); + if (mi == nullptr) + mi = findInterfaceMethod(interfaces[i]->GetInterfaces(), methodName, argTypes, bindingAttr); + } + return mi; +} + +// find method named methodName with signature as described by +// argTypes and binding attributes bindingAttr +MethodInfo^ InvokeMember::findMethod(Type ^type, const __wchar_t *methodName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr) { + // first try it directly + MethodInfo ^mi = type->GetMethod(gcnew String(methodName), bindingAttr, nullptr, argTypes, nullptr); + + // then try for all interfaces + if (mi == nullptr && type->IsInterface) { + mi = findInterfaceMethod(type->GetInterfaces(), methodName, argTypes, bindingAttr); + + // finally (still not found) check if its a method inherited from + // System.Object + if (mi == nullptr) + mi = findMethod(Object::typeid, methodName, argTypes, bindingAttr); + } + return mi; +} + +// provide informative message about which method wasn't found +void InvokeMember::throwMethodNotFoundError(Type ^type, const __wchar_t *methodName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr) { + String ^msg = String::Concat( + (int)(BindingFlags::Static & bindingAttr) ? "Static method not found: " : "Instance method not found: ", + type->FullName, + "::", + gcnew String(methodName) + ); + msg = String::Concat(msg, "("); + for (int i = 0; i < argTypes->Length; i++) { + if (i) + msg = String::Concat(msg, ","); + msg = String::Concat(msg, argTypes[i]->FullName); + } + msg = String::Concat(msg, ")"); + throw gcnew Exception (msg); +} + +// helper function to invoke static as well as instance methods +void* InvokeMember::invokeMethod(Object ^o, Type ^t, const __wchar_t *methodName, int nargs, void *args[], BindingFlags bindingAttr) { + try { + // first convert index arguments - nargs is the number of + // arguments, and args is an array of pointers to DotNetContainer + // objects + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs); + cli::array<Type^> ^realTypes = gcnew cli::array<Type^>(nargs); + for (int i = 0; i < nargs; i++) { + DotNetContainer *c = static_cast<DotNetContainer *>(args[i]); + realArgs[i] = c->getContainerObject(); + realTypes[i] = c->getContainerType(); + } + + MethodInfo ^mi = findMethod(t, methodName, realTypes, bindingAttr); + if (mi == nullptr) + throwMethodNotFoundError(t, methodName, realTypes, bindingAttr); + + Object ^newInstance = mi->Invoke(o, realArgs); + + // for arguments that were pass-by-reference update the object + // slots of the corresponding containers + cli::array<ParameterInfo^> ^pi = mi->GetParameters(); + for (int i = 0; i < nargs; i++) + if (pi[i]->ParameterType->IsByRef) { + DotNetContainer *c = static_cast<DotNetContainer *>(args[i]); + c->setContainerObject(realArgs[i]); + } + + if (mi->ReturnType->Equals(Void::typeid)) { + // return a "void" InvocationResult object if the method doesn't + // return anything + return new InvocationResult(); + } else { + return new InvocationResult(newInstance, mi->ReturnType); + } + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to invoke static as well as instance methods +void* InvokeMember::invokeMethodDirectly(void *methodInfo, int nargs, void *args[], bool staticp) { + try { + // first convert index arguments - nargs is the number of + // arguments, and args is an array of pointers to DotNetContainer + // objects + int offset = staticp ? 0 : 1; + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs - offset); + for (int i = 0; i + offset < nargs; i++) + realArgs[i] = static_cast<DotNetContainer *>(args[i + offset])->getContainerObject(); + + Object ^o = nullptr; + if (!staticp) + o = static_cast<DotNetContainer *>(args[0])->getContainerObject(); + + MethodInfo ^mi = safe_cast<MethodInfo ^>(static_cast<DotNetContainer *>(methodInfo)->getContainerObject()); + + Object ^newInstance = mi->Invoke(o, realArgs); + + // for arguments that were pass-by-reference update the object + // slots of the corresponding containers + cli::array<ParameterInfo^> ^pi = mi->GetParameters(); + for (int i = 0; i + offset < nargs; i++) + if (pi[i]->ParameterType->IsByRef) { + DotNetContainer *c = static_cast<DotNetContainer *>(args[i + offset]); + c->setContainerObject(realArgs[i]); + } + + if (mi->ReturnType->Equals(Void::typeid)) { + // return a "void" InvocationResult object if the method doesn't + // return anything + return new InvocationResult(); + } else { + return new InvocationResult(newInstance, mi->ReturnType); + } + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// below void pointers always point to DotNetContainer objects + +__declspec(dllexport) void* invokeInstanceMember(const __wchar_t *methodName, void *target, int nargs, void *args[]) { + DotNetContainer *container = static_cast<DotNetContainer *>(target); + Type ^t = container->getContainerType(); + Object ^o = container->getContainerObject(); + return InvokeMember::invokeMethod(o, t, methodName, nargs, args, static_cast<BindingFlags>(BindingFlags::Instance | BindingFlags::Public)); +} + +__declspec(dllexport) void* invokeInstanceMemberDirectly(void *methodInfo, int nargs, void *args[]) { + return InvokeMember::invokeMethodDirectly(methodInfo, nargs, args, false); +} + +__declspec(dllexport) void* invokeStaticMember(const __wchar_t *methodName, void *type, int nargs, void *args[]) { + Type ^t = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + return InvokeMember::invokeMethod(nullptr, t, methodName, nargs, args, static_cast<BindingFlags>(BindingFlags::Static | BindingFlags::Public)); +} + +__declspec(dllexport) void* invokeStaticMemberDirectly(void *methodInfo, int nargs, void *args[]) { + return InvokeMember::invokeMethodDirectly(methodInfo, nargs, args, true); +} + +// not directly related, but I didn't know where to put it... :) +// "shortcut" function used by DO-RDNZL-ARRAY (see Lisp code) - +// returns an array element for arrays of rank 1 +__declspec(dllexport) void *getArrayElement(void *ptr, int index) { + try { + Array ^array = safe_cast<Array ^>(static_cast<DotNetContainer *>(ptr)->getContainerObject()); + Type ^elementType = array->GetType()->GetElementType(); + + return new InvocationResult(array->GetValue(index), elementType); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +}
Added: trunk/rdnzl-cpp/RDNZL/InvokeMember.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/InvokeMember.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,49 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/InvokeMember.h,v 1.14 2008/02/14 07:34:32 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "InvocationResult.h" + +public ref class InvokeMember { + public: + static void* invokeMethod(Object ^o, Type ^t, const __wchar_t *methodName, int nargs, void *args [], BindingFlags bindingAttr); + static void* invokeMethodDirectly(void *methodInfo, int nargs, void *args [], bool staticp); + private: + static MethodInfo^ findInterfaceMethod(cli::array<Type^> ^interfaces, const __wchar_t *methodName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr); + static MethodInfo^ findMethod(Type ^type, const __wchar_t *methodName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr); + static void throwMethodNotFoundError(Type ^type, const __wchar_t *methodName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr); +}; + +extern "C" { + __declspec(dllexport) void *invokeInstanceMember(const __wchar_t *methodName, void *target, int nargs, void *args[]); + __declspec(dllexport) void* invokeInstanceMemberDirectly(void *methodInfo, int nargs, void *args[]); + __declspec(dllexport) void *invokeStaticMember(const __wchar_t *methodName, void *type, int nargs, void *args[]); + __declspec(dllexport) void* invokeStaticMemberDirectly(void *methodInfo, int nargs, void *args[]); + __declspec(dllexport) void *getArrayElement(void *ptr, int index); +}
Added: trunk/rdnzl-cpp/RDNZL/Property.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/Property.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,195 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/Property.cpp,v 1.17 2008/02/14 11:54:03 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" +#include "Property.h" + +// provide informative message about which property wasn't found +void Property::throwPropertyNotFoundError(Type ^type, const __wchar_t *propertyName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr) { + String ^msg = String::Concat( + (int)(BindingFlags::Static & bindingAttr) ? "Static property not found: " : "Instance property not found: ", + type->FullName, + "->", + gcnew String(propertyName) + ); + for (int i = 0; i < argTypes->Length; i++) + msg = String::Concat(msg, "[", argTypes[i]->FullName, "]"); + throw gcnew Exception (msg); +} + +// helper function to get values of static and instance properties +void *Property::getPropertyValue(Object ^o, Type ^t, const __wchar_t *propertyName, BindingFlags bindingAttr, int nargs, void *args[]) { + try { + // first convert index arguments - nargs is the number of + // arguments, and args is an array of pointers to DotNetContainer + // objects + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs); + cli::array<Type^> ^realTypes = gcnew cli::array<Type^>(nargs); + for (int i = 0; i < nargs; i++) { + DotNetContainer *c = static_cast<DotNetContainer *>(args[i]); + realArgs[i] = c->getContainerObject(); + realTypes[i] = c->getContainerType(); + } + + // find property by name, binding attributes and index signature + PropertyInfo ^pi = t->GetProperty(gcnew String(propertyName), bindingAttr, nullptr, nullptr, realTypes, nullptr); + + if (pi == nullptr) + throwPropertyNotFoundError(t, propertyName, realTypes, bindingAttr); + + return new InvocationResult(pi->GetValue(o, realArgs), pi->PropertyType); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to get values of static and instance properties +void *Property::getPropertyValueDirectly(void *propertyInfo, int nargs, void *args[], bool staticp) { + try { + // first convert index arguments - nargs is the number of + // arguments, and args is an array of pointers to DotNetContainer + // objects + int offset = staticp ? 0 : 1; + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs - offset); + for (int i = 0; i + offset < nargs; i++) + realArgs[i] = static_cast<DotNetContainer *>(args[i + offset])->getContainerObject(); + Object ^o = nullptr; + if (!staticp) + o = static_cast<DotNetContainer *>(args[0])->getContainerObject(); + + PropertyInfo ^pi = safe_cast<PropertyInfo ^>(static_cast<DotNetContainer *>(propertyInfo)->getContainerObject()); + + return new InvocationResult(pi->GetValue(o, realArgs), pi->PropertyType); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to set values of static and instance properties +void *Property::setPropertyValue(Object ^o, Type ^t, const __wchar_t *propertyName, BindingFlags bindingAttr, int nargs, void *args[]) { + try { + // first convert index arguments - nargs is the number of + // arguments, and args is an array of pointers to DotNetContainer + // objects + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs - 1); + cli::array<Type^> ^realTypes = gcnew cli::array<Type^>(nargs - 1); + for (int i = 1; i < nargs; i++) { + DotNetContainer *c = static_cast<DotNetContainer *>(args[i]); + realArgs[i - 1] = c->getContainerObject(); + realTypes[i - 1] = c->getContainerType(); + } + + // find property by name, binding attributes and index signature + PropertyInfo ^pi = t->GetProperty(gcnew String(propertyName), bindingAttr, nullptr, nullptr, realTypes, nullptr); + + if (pi == nullptr) + throwPropertyNotFoundError(t, propertyName, realTypes, bindingAttr); + + // note that the new value is the first element of args + pi->SetValue(o, static_cast<DotNetContainer *>(args[0])->getContainerObject(), realArgs); + return new InvocationResult(); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// helper function to set values of static and instance properties +void *Property::setPropertyValueDirectly(void *propertyInfo, int nargs, void *args[], bool staticp) { + try { + // first convert index arguments - nargs is the number of + // arguments, and args is an array of pointers to DotNetContainer + // objects + int offset = staticp ? 0 : 1; + cli::array<Object^> ^realArgs = gcnew cli::array<Object^>(nargs - 1 - offset); + for (int i = 1; i + offset < nargs; i++) + realArgs[i - 1] = static_cast<DotNetContainer *>(args[i + offset])->getContainerObject(); + + Object ^o = nullptr; + if (!staticp) + o = static_cast<DotNetContainer *>(args[1])->getContainerObject(); + + PropertyInfo ^pi = safe_cast<PropertyInfo ^>(static_cast<DotNetContainer *>(propertyInfo)->getContainerObject()); + + // note that the new value is the first element of args + pi->SetValue(o, static_cast<DotNetContainer *>(args[0])->getContainerObject(), realArgs); + return new InvocationResult(); + } catch (TargetInvocationException ^e) { + return new InvocationResult(e->InnerException, true); + } catch (Exception ^e) { + return new InvocationResult(e, true); + } +} + +// below void pointers always point to DotNetContainer objects + +__declspec(dllexport) void *getInstancePropertyValue(const __wchar_t *propertyName, void *target, int nargs, void *args[]) { + DotNetContainer *container = static_cast<DotNetContainer *>(target); + Type ^t = container->getContainerType(); + Object ^o = container->getContainerObject(); + return Property::getPropertyValue(o, t, propertyName, static_cast<BindingFlags>(BindingFlags::Instance | BindingFlags::Public), nargs, args); +} + +__declspec(dllexport) void *getStaticPropertyValue(const __wchar_t *propertyName, void *type, int nargs, void *args[]) { + Type ^t = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + return Property::getPropertyValue(nullptr, t, propertyName, static_cast<BindingFlags>(BindingFlags::Static | BindingFlags::Public), nargs, args); +} + +__declspec(dllexport) void *setInstancePropertyValue(const __wchar_t *propertyName, void *target, int nargs, void *args[]) { + DotNetContainer *container = static_cast<DotNetContainer *>(target); + Type ^t = container->getContainerType(); + Object ^o = container->getContainerObject(); + return Property::setPropertyValue(o, t, propertyName, static_cast<BindingFlags>(BindingFlags::Instance | BindingFlags::Public), nargs, args); +} + +__declspec(dllexport) void *setStaticPropertyValue(const __wchar_t *propertyName, void *type, int nargs, void *args[]) { + Type ^t = safe_cast<Type ^>(static_cast<DotNetContainer *>(type)->getContainerObject()); + return Property::setPropertyValue(nullptr, t, propertyName, static_cast<BindingFlags>(BindingFlags::Static | BindingFlags::Public), nargs, args); +} + +__declspec(dllexport) void *getInstancePropertyValueDirectly(void *propertyInfo, int nargs, void *args[]) { + return Property::getPropertyValueDirectly(propertyInfo, nargs, args, false); +} + +__declspec(dllexport) void *getStaticPropertyValueDirectly(void *propertyInfo, int nargs, void *args[]) { + return Property::getPropertyValueDirectly(propertyInfo, nargs, args, true); +} + +__declspec(dllexport) void *setInstancePropertyValueDirectly(void *propertyInfo, int nargs, void *args[]) { + return Property::setPropertyValueDirectly(propertyInfo, nargs, args, false); +} + +__declspec(dllexport) void *setStaticPropertyValueDirectly(void *propertyInfo, int nargs, void *args[]) { + return Property::setPropertyValueDirectly(propertyInfo, nargs, args, true); +} +
Added: trunk/rdnzl-cpp/RDNZL/Property.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/Property.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,52 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/Property.h,v 1.14 2008/02/14 07:34:32 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#include "InvocationResult.h" + +public ref class Property { + public: + static void *getPropertyValue(Object ^o, Type ^t, const __wchar_t *propertyName, BindingFlags bindingAttr, int nargs, void *args[]); + static void *setPropertyValue(Object ^o, Type ^t, const __wchar_t *propertyName, BindingFlags bindingAttr, int nargs, void *args[]); + static void *getPropertyValueDirectly(void *propertyInfo, int nargs, void *args[], bool staticp); + static void *setPropertyValueDirectly(void *propertyInfo, int nargs, void *args[], bool staticp); + private: + static void throwPropertyNotFoundError(Type ^type, const __wchar_t *propertyName, cli::array<Type^> ^argTypes, BindingFlags bindingAttr); +}; + +extern "C" { + __declspec(dllexport) void *getInstancePropertyValue(const __wchar_t *propertyName, void *target, int nargs, void *args[]); + __declspec(dllexport) void *setInstancePropertyValue(const __wchar_t *propertyName, void *target, int nargs, void *args[]); + __declspec(dllexport) void *getStaticPropertyValue(const __wchar_t *propertyName, void *type, int nargs, void *args[]); + __declspec(dllexport) void *setStaticPropertyValue(const __wchar_t *propertyName, void *type, int nargs, void *args[]); + __declspec(dllexport) void *getInstancePropertyValueDirectly(void *propertyInfo, int nargs, void *args[]); + __declspec(dllexport) void *getStaticPropertyValueDirectly(void *propertyInfo, int nargs, void *args[]); + __declspec(dllexport) void *setInstancePropertyValueDirectly(void *propertyInfo, int nargs, void *args[]); + __declspec(dllexport) void *setStaticPropertyValueDirectly(void *propertyInfo, int nargs, void *args[]); +}
Added: trunk/rdnzl-cpp/RDNZL/RDNZL.vcproj ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/RDNZL.vcproj Wed Apr 30 04:30:03 2008 @@ -0,0 +1,304 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8,00" + Name="RDNZL" + ProjectGUID="{08A74849-5B79-4488-8F41-731C19FE3A13}" + RootNamespace="RDNZL" + Keyword="ManagedCProj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="4" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + UsePrecompiledHeader="2" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/NOENTRY" + AdditionalDependencies="msvcrt.lib" + OutputFile="$(OutDir)/RDNZL.dll" + LinkIncremental="2" + IgnoreDefaultLibraryNames="libcmtd.lib" + ModuleDefinitionFile="rdnzl.def" + ForceSymbolReferences="__DllMainCRTStartup@12" + GenerateDebugInformation="true" + ResourceOnlyDLL="false" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + PreprocessorDefinitions="WIN32;NDEBUG" + MinimalRebuild="false" + RuntimeLibrary="2" + UsePrecompiledHeader="2" + WarningLevel="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/NOENTRY" + AdditionalDependencies="ptrustm.lib" + OutputFile="$(OutDir)/RDNZL.dll" + LinkIncremental="1" + IgnoreDefaultLibraryNames="msvcmrt.lib" + ModuleDefinitionFile="rdnzl.def" + GenerateDebugInformation="true" + CLRThreadAttribute="2" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath="AssemblyInfo.cpp" + > + </File> + <File + RelativePath=".\DelegateAdapter.cpp" + > + </File> + <File + RelativePath=".\DelegateAdapterBuilder.cpp" + > + </File> + <File + RelativePath="DotNetContainer.cpp" + > + </File> + <File + RelativePath="DotNetReference.cpp" + > + </File> + <File + RelativePath=".\Field.cpp" + > + </File> + <File + RelativePath="InvocationResult.cpp" + > + </File> + <File + RelativePath="InvokeConstructor.cpp" + > + </File> + <File + RelativePath=".\InvokeMember.cpp" + > + </File> + <File + RelativePath=".\Property.cpp" + > + </File> + <File + RelativePath=".\rdnzl.def" + > + </File> + <File + RelativePath="Stdafx.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\DelegateAdapter.h" + > + </File> + <File + RelativePath=".\DelegateAdapterBuilder.h" + > + </File> + <File + RelativePath="DotNetContainer.h" + > + </File> + <File + RelativePath="DotNetReference.h" + > + </File> + <File + RelativePath=".\Field.h" + > + </File> + <File + RelativePath="InvocationResult.h" + > + </File> + <File + RelativePath="InvokeConstructor.h" + > + </File> + <File + RelativePath=".\InvokeMember.h" + > + </File> + <File + RelativePath=".\Property.h" + > + </File> + <File + RelativePath="Stdafx.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;r" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject>
Added: trunk/rdnzl-cpp/RDNZL/Stdafx.cpp ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/Stdafx.cpp Wed Apr 30 04:30:03 2008 @@ -0,0 +1,38 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/Stdafx.cpp,v 1.12 2008/02/14 11:54:03 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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 "stdafx.h" + +// see http://msdn.microsoft.com/library/en-us/vcmex/html/vcconconvertingmanagedextensionsforcprojectsfrompureintermediatelanguagetomixedmode.asp?frame=true + +extern "C" __declspec(dllexport) void __stdcall DllEnsureInit(void) { + System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA; +} + +extern "C" __declspec(dllexport) void __stdcall DllForceTerm(void) { +}
Added: trunk/rdnzl-cpp/RDNZL/Stdafx.h ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/Stdafx.h Wed Apr 30 04:30:03 2008 @@ -0,0 +1,41 @@ +// $Header: /usr/local/cvsrep/rdnzl-cpp/RDNZL/Stdafx.h,v 1.14 2008/02/14 11:54:03 edi Exp $ +// +// Copyright (c) 2004-2008, Dr. Edmund Weitz. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * 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. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +// 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 AUTHOR 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. + +#pragma once + +#using <mscorlib.dll> + +#include <string.h> +#include <vcclr.h> + +using namespace System; +using namespace System::Reflection; +using namespace System::Reflection::Emit; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Threading;
Added: trunk/rdnzl-cpp/RDNZL/rdnzl.def ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/RDNZL/rdnzl.def Wed Apr 30 04:30:03 2008 @@ -0,0 +1,5 @@ +LIBRARY RDNZL + +EXPORTS + DllEnsureInit PRIVATE + DllForceTerm PRIVATE
Added: trunk/rdnzl-cpp/README.txt ============================================================================== --- (empty file) +++ trunk/rdnzl-cpp/README.txt Wed Apr 30 04:30:03 2008 @@ -0,0 +1,6 @@ +This is the code for the "glue" library RDNZL.dll which belongs to the +RDNZL .NET bridge for Common Lisp. + +This C++ source code is known to work with Microsoft Visual Studio 2005. + +For more info about RDNZL see http://weitz.de/rdnzl/.