diff --git a/CPPInterop.sln b/CPPInterop.sln index b9758523..dde0c0bb 100644 --- a/CPPInterop.sln +++ b/CPPInterop.sln @@ -1,45 +1,45 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.VisualC.Interop", "Mono.VisualC.Interop\Mono.VisualC.Interop.csproj", "{4A864586-93C5-4DC1-8A80-F094A88506D7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPPPOC", "CPPPOC\CPPPOC.csproj", "{7F309FEA-3A3F-40B1-BBF9-A09796253202}" -EndProject -Project("{2857B73E-F847-4B02-9238-064979017E93}") = "CPPTest", "CPPTest\CPPTest.cproj", "{B01E6282-144E-481A-8E1F-95F708DFBC2D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Linux|Any CPU = Linux|Any CPU - Mac|Any CPU = Mac|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4A864586-93C5-4DC1-8A80-F094A88506D7}.Linux|Any CPU.ActiveCfg = Linux|Any CPU - {4A864586-93C5-4DC1-8A80-F094A88506D7}.Linux|Any CPU.Build.0 = Linux|Any CPU - {4A864586-93C5-4DC1-8A80-F094A88506D7}.Mac|Any CPU.ActiveCfg = Mac|Any CPU - {4A864586-93C5-4DC1-8A80-F094A88506D7}.Mac|Any CPU.Build.0 = Mac|Any CPU - {7F309FEA-3A3F-40B1-BBF9-A09796253202}.Linux|Any CPU.ActiveCfg = Linux|Any CPU - {7F309FEA-3A3F-40B1-BBF9-A09796253202}.Linux|Any CPU.Build.0 = Linux|Any CPU - {7F309FEA-3A3F-40B1-BBF9-A09796253202}.Mac|Any CPU.ActiveCfg = Mac|Any CPU - {7F309FEA-3A3F-40B1-BBF9-A09796253202}.Mac|Any CPU.Build.0 = Mac|Any CPU - {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Linux|Any CPU.ActiveCfg = Linux|Any CPU - {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Linux|Any CPU.Build.0 = Linux|Any CPU - {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Mac|Any CPU.ActiveCfg = Mac|Any CPU - {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Mac|Any CPU.Build.0 = Mac|Any CPU - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = CPPPOC\CPPPOC.csproj - Policies = $0 - $0.TextStylePolicy = $1 - $1.TabWidth = 8 - $1.NoTabsAfterNonTabs = True - $1.RemoveTrailingWhitespace = True - $1.inheritsSet = VisualStudio - $1.inheritsScope = text/plain - $1.scope = text/x-csharp - $0.CSharpFormattingPolicy = $2 - $2.inheritsSet = Mono - $2.inheritsScope = text/x-csharp - $2.scope = text/x-csharp - name = CPPInterop - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.VisualC.Interop", "Mono.VisualC.Interop\Mono.VisualC.Interop.csproj", "{4A864586-93C5-4DC1-8A80-F094A88506D7}" +EndProject +Project("{2857B73E-F847-4B02-9238-064979017E93}") = "CPPTestLib", "CPPTestLib\CPPTestLib.cproj", "{B01E6282-144E-481A-8E1F-95F708DFBC2D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}.Release|Any CPU.Build.0 = Release|Any CPU + {4A864586-93C5-4DC1-8A80-F094A88506D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A864586-93C5-4DC1-8A80-F094A88506D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A864586-93C5-4DC1-8A80-F094A88506D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A864586-93C5-4DC1-8A80-F094A88506D7}.Release|Any CPU.Build.0 = Release|Any CPU + {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Mono.VisualC.Interop\Mono.VisualC.Interop.csproj + Policies = $0 + $0.TextStylePolicy = $1 + $1.TabWidth = 8 + $1.NoTabsAfterNonTabs = True + $1.RemoveTrailingWhitespace = True + $1.inheritsSet = VisualStudio + $1.inheritsScope = text/plain + $1.scope = text/x-csharp + $0.CSharpFormattingPolicy = $2 + $2.inheritsSet = Mono + $2.inheritsScope = text/x-csharp + $2.scope = text/x-csharp + name = CPPInterop + EndGlobalSection +EndGlobal diff --git a/CPPPOC/AssemblyInfo.cs b/CPPPOC/AssemblyInfo.cs deleted file mode 100644 index 84e0e90c..00000000 --- a/CPPPOC/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -// AssemblyInfo.cs created with MonoDevelop -// User: alex at 17:40 03/14/2009 -// -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("CPPPOC")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile("")] diff --git a/CPPPOC/Main.cs b/CPPPOC/Main.cs deleted file mode 100644 index 298fb1d5..00000000 --- a/CPPPOC/Main.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Main.cs created with MonoDevelop -// User: alex at 17:40 03/14/2009 -// -using System; -using Mono.VisualC.Interop; - -using System.Runtime.InteropServices; - -namespace CPPPOC -{ - class MainClass - { - public static void Main(string[] args) - { - // bind all wrapper classes to their native implementations - CppLibrary cppTest = new CppLibrary("CPPTest", new Mono.VisualC.Interop.ABI.ItaniumAbi()); - CSimpleClass.Bind(cppTest); - - CSimpleClass csc1 = new CSimpleClass(CreateCSimpleSubClass(10)); - CSimpleClass csc2 = new CSimpleClass(2); - try { - //TODO: This still calls managed V0 on CSimpleClass first, even though it's an - // instance of a more-derived class. - csc1.V0(25, 50); - csc1.M0(); - Console.WriteLine("Managed code got value: {0}", csc1.value); - csc2.M0(); - Console.WriteLine("Managed code got value: {0}", csc2.value); - - csc1.value = 100; - csc1.V2(); - - csc2.value = 200; - csc2.V2(); - - } finally { - DestroyCSimpleSubClass(csc1.Native); - csc1.Dispose(); - csc2.Dispose(); - } - } - - [DllImport("CPPTest")] - public static extern IntPtr CreateCSimpleSubClass(int value); - - [DllImport("CPPTest")] - public static extern void DestroyCSimpleSubClass(IntPtr obj); - } -} \ No newline at end of file diff --git a/CPPTest/CPPTest.cpp b/CPPTest/CPPTest.cpp deleted file mode 100644 index 08e06383..00000000 --- a/CPPTest/CPPTest.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * CPPTest.cpp - * CPPTest - * - * Created by Alex Corrado on 3/14/09. - * Copyright 2009 __MyCompanyName__. All rights reserved. - * - */ - -#include -#include "CPPTest.h" - -CSimpleClass::CSimpleClass(int value) : value(value) { - printf("CSimpleClass(%d)\n", value); - this->value = value; -} - -CSimpleSubClass::CSimpleSubClass(int value) : CSimpleClass(value) { - printf("CSimpleSubClass(%d)\n", value); -} - -CSimpleClass::~CSimpleClass() { - printf("~CSimpleClass\n"); -} - -void CSimpleClass::M0() { - printf("C++/CSimpleClass::M0()\n"); - V0(value, value + 1); - V1(value); - V2(); -} - -void CSimpleClass::V0(int x, int y) { - printf("C++/CSimpleClass::V0(%d, %d)\n", x, y); -} - -void CSimpleSubClass::V0(int x, int y) { - printf("C++/CSimpleSubClass::V0(%d, %d)\n", x, y); -} - -void CSimpleClass::M1(int x) { - printf("C++/CSimpleClass::M1(%d)\n", x); - V0(x, value); - V1(x); - V2(); -} - -void CSimpleClass::V1(int x) { - printf("C++/CSimpleClass::V1(%d)\n", x); -} - -void CSimpleSubClass::V1(int x) { - printf("C++/CSimpleSubClass::V1(%d)\n", x); -} - -void CSimpleClass::M2(int x, int y) { - -} - -void CSimpleClass::V2() { - printf("C++/CSimpleClass::V2() - value: %d\n", value); -} - -void CSimpleSubClass::V2() { - printf("C++/CSimpleSubClass::V2() - value: %d\n", value); -} diff --git a/CPPTest/CPPTest.cproj b/CPPTest/CPPTest.cproj deleted file mode 100644 index 171450b0..00000000 --- a/CPPTest/CPPTest.cproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - Debug - AnyCPU - 8.0.50727 - 2.0 - {B01E6282-144E-481A-8E1F-95F708DFBC2D} - - - - C - Bin - - - true - bin\Debug - DEBUG MONODEVELOP - . - CPPTest - SharedLibrary - - - - - - - - bin\Release - MONODEVELOP - . - 3 - CPPTest - Bin - - - true - build\Debug - -dynamic - DEBUG MONODEVELOP - . - - - - - - - libCPPTest.dylib - Bin - - - build\Debug - DEBUG MONODEVELOP - SharedLibrary - libCPPTest.so - - - - - - - - - - - - - \ No newline at end of file diff --git a/CPPTest/CPPTest.h b/CPPTest/CPPTest.h deleted file mode 100644 index 294c4d86..00000000 --- a/CPPTest/CPPTest.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * CPPTest.h - * CPPTest - * - * Created by Alex Corrado on 3/14/09. - * Copyright 2009 __MyCompanyName__. All rights reserved. - * - */ - -#ifndef CPPTest_ -#define CPPTest_ - -/* The classes below are exported */ -#pragma GCC visibility push(default) - -class CSimpleClass { -public: - int value; - CSimpleClass(int value); - ~CSimpleClass(); - void M0(); - virtual void V0(int x, int y); - void M1(int x); - virtual void V1(int x); - void M2(int x, int y); - virtual void V2(); -}; - -class CSimpleSubClass : CSimpleClass { -public: - CSimpleSubClass(int value); - virtual void V0(int x, int y); - virtual void V1(int x); - virtual void V2(); -}; - -extern "C" { - CSimpleSubClass* CreateCSimpleSubClass(int value) { - return new CSimpleSubClass(value); - } - void DestroyCSimpleSubClass(CSimpleSubClass* obj) { - delete obj; - } -} - -#pragma GCC visibility pop -#endif diff --git a/CPPTestLib/CPPTestLib.cproj b/CPPTestLib/CPPTestLib.cproj new file mode 100644 index 00000000..41c3e0c9 --- /dev/null +++ b/CPPTestLib/CPPTestLib.cproj @@ -0,0 +1,39 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {B01E6282-144E-481A-8E1F-95F708DFBC2D} + + + + CPP + Bin + + + true + bin\Debug + DEBUG MONODEVELOP + . + CPPTestLib + SharedLibrary + + + + + + + + bin\Release + MONODEVELOP + . + 3 + CPPTest + Bin + + + + + \ No newline at end of file diff --git a/CPPTestLib/CSimpleClass.cpp b/CPPTestLib/CSimpleClass.cpp new file mode 100644 index 00000000..34ae83b3 --- /dev/null +++ b/CPPTestLib/CSimpleClass.cpp @@ -0,0 +1,86 @@ +/* + * CPPTest.cpp + * CPPTest + * + * Created by Alex Corrado on 3/14/09. + * Copyright 2009 __MyCompanyName__. All rights reserved. + * + */ + +#include + +/* The classes below are exported */ +#pragma GCC visibility push(default) + +class CSimpleClass { +public: + int value; + CSimpleClass (int value) : value (value) + { + printf ("CSimpleClass(%d)\n", value); + this->value = value; + } + + ~CSimpleClass () + { + printf ("~CSimpleClass\n"); + } + + void M0 () + { + printf ("C++/CSimpleClass::M0()\n"); + V0 (value, value + 1); + V1 (value); + } + + virtual void V0 (int x, int y) + { + printf ("C++/CSimpleClass::V0(%d, %d)\n", x, y); + } + + void M1 (int x) + { + printf ("C++/CSimpleClass::M1(%d)\n", x); + } + + virtual void V1(int x) + { + printf("C++/CSimpleClass::V1(%d)\n", x); + } + + void M2(int x, int y) + { + printf ("C++/CSimpleClass::M2(%d, %d)\n", x, y); + } +}; + +class CSimpleSubClass : CSimpleClass { +public: + CSimpleSubClass (int value) : CSimpleClass (value) + { + printf("CSimpleSubClass(%d)\n", value); + } + + virtual void V0 (int x, int y) + { + printf ("C++/CSimpleSubClass::V0(%d, %d)\n", x, y); + } + + virtual void V1 (int x) + { + printf("C++/CSimpleSubClass::V1(%d)\n", x); + } +}; + +extern "C" { + CSimpleSubClass* CreateCSimpleSubClass (int value) + { + return new CSimpleSubClass(value); + } + void DestroyCSimpleSubClass (CSimpleSubClass* obj) + { + delete obj; + } +} + +#pragma GCC visibility pop diff --git a/Mono.VisualC.Interop/ABI/CppAbi.cs b/Mono.VisualC.Interop/ABI/CppAbi.cs index a5509dd4..09572b51 100644 --- a/Mono.VisualC.Interop/ABI/CppAbi.cs +++ b/Mono.VisualC.Interop/ABI/CppAbi.cs @@ -21,19 +21,19 @@ namespace Mono.VisualC.Interop.ABI { //TODO: Allow interface to override default calling convention public abstract class CppAbi { - protected ModuleBuilder implModule; - protected TypeBuilder implType; + protected ModuleBuilder impl_module; + protected TypeBuilder impl_type; - protected Type interfaceType, layoutType, wrapperType; - protected string library, className; + protected Type interface_type, layout_type, wrapper_type; + protected string library, class_name; protected VTable vtable; - protected FieldBuilder vtableField; - protected ILGenerator ctorIL; + protected FieldBuilder vtable_field; + protected ILGenerator ctor_il; // default settings that subclasses can override: - protected MakeVTableDelegate makeVTableMethod = VTable.DefaultImplementation; - protected MemberFilter vtableOverrideFilter = VTable.BindToSignatureAndAttribute; + protected MakeVTableDelegate make_vtable_method = VTable.DefaultImplementation; + protected MemberFilter vtable_override_filter = VTable.BindToSignatureAndAttribute; private struct EmptyNativeLayout { } @@ -46,30 +46,30 @@ namespace Mono.VisualC.Interop.ABI { where NLayout : struct //where Iface : ICppClassInstantiatable or ICppClassOverridable { - this.implModule = CppLibrary.interopModule; + this.impl_module = CppLibrary.interopModule; this.library = lib; - this.className = className; - this.interfaceType = typeof (Iface); - this.layoutType = typeof (NLayout); - this.wrapperType = wrapperType; + this.class_name = className; + this.interface_type = typeof (Iface); + this.layout_type = typeof (NLayout); + this.wrapper_type = wrapperType; DefineImplType (); var properties = ( // get all properties defined on the interface - from property in interfaceType.GetProperties () + from property in interface_type.GetProperties () select property ).Union( // ... as well as those defined on inherited interfaces - from iface in interfaceType.GetInterfaces () + from iface in interface_type.GetInterfaces () from property in iface.GetProperties () select property ); var methods = ( // get all methods defined on the interface - from method in interfaceType.GetMethods () + from method in interface_type.GetMethods () orderby method.MetadataToken select method ).Union( // ... as well as those defined on inherited interfaces - from iface in interfaceType.GetInterfaces () + from iface in interface_type.GetInterfaces () from method in iface.GetMethods () select method ); @@ -77,9 +77,9 @@ namespace Mono.VisualC.Interop.ABI { var managedOverrides = from method in methods where Modifiers.IsVirtual (method) orderby method.MetadataToken - select GetManagedOverrideTrampoline (method, vtableOverrideFilter); + select GetManagedOverrideTrampoline (method, vtable_override_filter); - vtable = makeVTableMethod (managedOverrides.ToArray ()); + vtable = make_vtable_method (managedOverrides.ToArray ()); // Implement all methods int vtableIndex = 0; @@ -98,15 +98,15 @@ namespace Mono.VisualC.Interop.ABI { foreach (var property in properties) DefineProperty (property); - ctorIL.Emit (OpCodes.Ret); - return (Iface)Activator.CreateInstance (implType.CreateType (), vtable); + ctor_il.Emit (OpCodes.Ret); + return (Iface)Activator.CreateInstance (impl_type.CreateType (), vtable); } // These methods might be more commonly overridden for a given C++ ABI: public virtual MethodType GetMethodType (MethodInfo imethod) { - if (imethod.Name.Equals (className)) + if (imethod.Name.Equals (class_name)) return MethodType.NativeCtor; else if (imethod.Name.Equals ("Alloc")) return MethodType.ManagedAlloc; @@ -125,7 +125,7 @@ namespace Mono.VisualC.Interop.ABI { // By default: native size = C++ class size + field offset padding (usually just vtable pointer) // TODO: Only include vtable ptr if there are virtual functions? Here I guess it doesn't really matter, // we're just allocing extra memory. - return Marshal.SizeOf (layoutType) + FieldOffsetPadding; + return Marshal.SizeOf (layout_type) + FieldOffsetPadding; } } @@ -137,20 +137,20 @@ namespace Mono.VisualC.Interop.ABI { protected virtual void DefineImplType () { - implType = implModule.DefineType (implModule.Name + "_" + interfaceType.Name + "_Impl", + impl_type = impl_module.DefineType (impl_module.Name + "_" + interface_type.Name + "_Impl", TypeAttributes.Class | TypeAttributes.Sealed); - implType.AddInterfaceImplementation (interfaceType); + impl_type.AddInterfaceImplementation (interface_type); - vtableField = implType.DefineField ("_vtable", typeof (VTable), FieldAttributes.InitOnly | FieldAttributes.Private); - ConstructorBuilder ctor = implType.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, + vtable_field = impl_type.DefineField ("_vtable", typeof (VTable), FieldAttributes.InitOnly | FieldAttributes.Private); + ConstructorBuilder ctor = impl_type.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof (VTable) }); - ctorIL = ctor.GetILGenerator (); + ctor_il = ctor.GetILGenerator (); // this._vtable = (VTable passed to constructor) - ctorIL.Emit (OpCodes.Ldarg_0); - ctorIL.Emit (OpCodes.Ldarg_1); - ctorIL.Emit (OpCodes.Stfld, vtableField); + ctor_il.Emit (OpCodes.Ldarg_0); + ctor_il.Emit (OpCodes.Ldarg_1); + ctor_il.Emit (OpCodes.Stfld, vtable_field); } protected virtual MethodBuilder DefineMethod (MethodInfo interfaceMethod, int index) @@ -186,7 +186,7 @@ namespace Mono.VisualC.Interop.ABI { MethodInfo nativeMethod; if (Modifiers.IsVirtual (interfaceMethod)) - nativeMethod = vtable.PrepareVirtualCall (interfaceMethod, il, vtableField, nativePtr, index); + nativeMethod = vtable.PrepareVirtualCall (interfaceMethod, il, vtable_field, nativePtr, index); else nativeMethod = GetPInvokeForMethod (interfaceMethod); @@ -223,11 +223,11 @@ namespace Mono.VisualC.Interop.ABI { // C++ interface properties are either to return the VTable or to access C++ fields if (retType.IsGenericType && retType.GetGenericTypeDefinition ().Equals (typeof (CppField<>))) { // define a new field for the property - fieldData = implType.DefineField ("__" + propName + "_Data", retType, FieldAttributes.InitOnly | FieldAttributes.Private); + fieldData = impl_type.DefineField ("__" + propName + "_Data", retType, FieldAttributes.InitOnly | FieldAttributes.Private); // init our field data with a new instance of CppField // first, get field offset - ctorIL.Emit (OpCodes.Ldarg_0); + ctor_il.Emit (OpCodes.Ldarg_0); /* TODO: Code prolly should not emit hardcoded offsets n such, in case we end up saving these assemblies in the future. * Something more like this perhaps? (need to figure out how to get field offset padding into this) @@ -236,20 +236,20 @@ namespace Mono.VisualC.Interop.ABI { * ctorIL.Emit(OpCodes.Ldstr, propName); * ctorIL.Emit(OpCodes.Call, typeof(Marshal).GetMethod("OffsetOf")); */ - int fieldOffset = ((int)Marshal.OffsetOf (layoutType, propName)) + FieldOffsetPadding; - ctorIL.Emit (OpCodes.Ldc_I4, fieldOffset); - ctorIL.Emit (OpCodes.Newobj, retType.GetConstructor (new Type[] { typeof(int) })); + int fieldOffset = ((int)Marshal.OffsetOf (layout_type, propName)) + FieldOffsetPadding; + ctor_il.Emit (OpCodes.Ldc_I4, fieldOffset); + ctor_il.Emit (OpCodes.Newobj, retType.GetConstructor (new Type[] { typeof(int) })); - ctorIL.Emit (OpCodes.Stfld, fieldData); + ctor_il.Emit (OpCodes.Stfld, fieldData); } else if (retType.Equals (typeof (VTable))) - fieldData = vtableField; + fieldData = vtable_field; else throw new InvalidProgramException ("Properties in C++ interface can only be of type CppField."); - PropertyBuilder fieldProp = implType.DefineProperty (propName, PropertyAttributes.None, retType, Type.EmptyTypes); + PropertyBuilder fieldProp = impl_type.DefineProperty (propName, PropertyAttributes.None, retType, Type.EmptyTypes); MethodAttributes methodAttr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig; - MethodBuilder fieldGetter = implType.DefineMethod (methodName, methodAttr, retType, Type.EmptyTypes); + MethodBuilder fieldGetter = impl_type.DefineMethod (methodName, methodAttr, retType, Type.EmptyTypes); ILGenerator il = fieldGetter.GetILGenerator (); il.Emit (OpCodes.Ldarg_0); @@ -271,13 +271,13 @@ namespace Mono.VisualC.Interop.ABI { if (targetMethod == null) return null; - Type delegateType = Util.GetDelegateTypeForMethodInfo (implModule, interfaceMethod); + Type delegateType = Util.GetDelegateTypeForMethodInfo (impl_module, interfaceMethod); Type[] parameterTypes = Util.GetMethodParameterTypes (interfaceMethod, true); // TODO: According to http://msdn.microsoft.com/en-us/library/w16z8yc4.aspx // The dynamic method created with this constructor has access to public and internal members of all the types contained in module m. // This does not appear to hold true, so we also disable JIT visibility checks. - DynamicMethod trampolineIn = new DynamicMethod (wrapperType.Name + "_" + interfaceMethod.Name + "_FromNative", interfaceMethod.ReturnType, + DynamicMethod trampolineIn = new DynamicMethod (wrapper_type.Name + "_" + interfaceMethod.Name + "_FromNative", interfaceMethod.ReturnType, parameterTypes, typeof (CppInstancePtr).Module, true); Util.ApplyMethodParameterAttributes (interfaceMethod, trampolineIn); @@ -295,7 +295,7 @@ namespace Mono.VisualC.Interop.ABI { il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldc_I4, NativeSize); - MethodInfo getManagedObj = typeof (CppInstancePtr).GetMethod ("GetManaged", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod (wrapperType); + MethodInfo getManagedObj = typeof (CppInstancePtr).GetMethod ("GetManaged", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod (wrapper_type); il.Emit (OpCodes.Call, getManagedObj); } @@ -311,7 +311,7 @@ namespace Mono.VisualC.Interop.ABI { protected virtual MethodInfo FindManagedOverrideTarget (MethodInfo interfaceMethod, MemberFilter filter) { - MemberInfo[] possibleMembers = wrapperType.FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic | + MemberInfo[] possibleMembers = wrapper_type.FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, filter, interfaceMethod); if (possibleMembers.Length > 1) @@ -328,7 +328,7 @@ namespace Mono.VisualC.Interop.ABI { { Type[] parameterTypes = Util.GetMethodParameterTypes (interfaceMethod, false); - MethodBuilder methodBuilder = implType.DefineMethod (interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, + MethodBuilder methodBuilder = impl_type.DefineMethod (interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, interfaceMethod.ReturnType, parameterTypes); Util.ApplyMethodParameterAttributes (interfaceMethod, methodBuilder); return methodBuilder; @@ -345,7 +345,7 @@ namespace Mono.VisualC.Interop.ABI { Type[] parameterTypes = Util.GetMethodParameterTypes (signature, true); - MethodBuilder builder = implType.DefinePInvokeMethod ("__$" + signature.Name + "_Impl", library, entryPoint, + MethodBuilder builder = impl_type.DefinePInvokeMethod ("__$" + signature.Name + "_Impl", library, entryPoint, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Any, signature.ReturnType, parameterTypes, DefaultCallingConvention, CharSet.Ansi); @@ -364,7 +364,7 @@ namespace Mono.VisualC.Interop.ABI { //TODO: Do not hard-emit native size in case assembly is saved? il.Emit (OpCodes.Ldc_I4, NativeSize); - if (wrapperType != null) { + if (wrapper_type != null) { // load managed object il.Emit (OpCodes.Ldarg_1); @@ -424,7 +424,7 @@ namespace Mono.VisualC.Interop.ABI { { // this._vtable.InitInstance (nativePtr); il.Emit (OpCodes.Ldarg_0); - il.Emit (OpCodes.Ldfld, vtableField); + il.Emit (OpCodes.Ldfld, vtable_field); il.Emit (OpCodes.Ldloc_S, nativePtr); EmitVTableOp (il, typeof (VTable).GetMethod ("InitInstance"), 2, false); } @@ -433,7 +433,7 @@ namespace Mono.VisualC.Interop.ABI { { // this._vtable.ResetInstance (nativePtr); il.Emit (OpCodes.Ldarg_0); - il.Emit (OpCodes.Ldfld, vtableField); + il.Emit (OpCodes.Ldfld, vtable_field); il.Emit (OpCodes.Ldloc_S, nativePtr); EmitVTableOp (il, typeof(VTable).GetMethod ("ResetInstance"), 2, false); } @@ -454,7 +454,7 @@ namespace Mono.VisualC.Interop.ABI { Label dontPushOrThrow = il.DefineLabel (); il.Emit (OpCodes.Ldarg_0); // load this - il.Emit (OpCodes.Ldfld, vtableField); // load this._vtable + il.Emit (OpCodes.Ldfld, vtable_field); // load this._vtable il.Emit (OpCodes.Brfalse_S, noVirt); // if (vtableInfo == null) goto noVirt il.Emit (OpCodes.Callvirt, method); // call method diff --git a/Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs b/Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs index 601942c5..abb94136 100644 --- a/Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs +++ b/Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs @@ -1,3 +1,11 @@ +// +// Mono.VisualC.Interop.ABI.ItaniumAbi.cs: An implementation of the Itanium C++ ABI +// +// Author: +// Alexander Corrado (alexander.corrado@gmail.com) +// +// Copyright (C) 2010 Alexander Corrado +// using System; using System.Text; @@ -5,10 +13,11 @@ using System.Reflection; using System.Runtime.InteropServices; namespace Mono.VisualC.Interop.ABI { - public class ItaniumAbi : CppAbi { - public ItaniumAbi() {} + public ItaniumAbi () + { + } public override CallingConvention DefaultCallingConvention { get { @@ -16,13 +25,14 @@ namespace Mono.VisualC.Interop.ABI { } } - public override string GetMangledMethodName(MethodInfo methodInfo) { + public override string GetMangledMethodName (MethodInfo methodInfo) + { string methodName = methodInfo.Name; - MethodType methodType = GetMethodType(methodInfo); - ParameterInfo[] parameters = methodInfo.GetParameters(); + MethodType methodType = GetMethodType (methodInfo); + ParameterInfo[] parameters = methodInfo.GetParameters (); StringBuilder nm = new StringBuilder("_ZN", 30); - nm.Append(className.Length).Append(className); + nm.Append(class_name.Length).Append(class_name); switch (methodType) { diff --git a/Mono.VisualC.Interop/ABI/Impl/VirtualOnlyAbi.cs b/Mono.VisualC.Interop/ABI/Impl/VirtualOnlyAbi.cs index ea620bfa..177d4eb3 100644 --- a/Mono.VisualC.Interop/ABI/Impl/VirtualOnlyAbi.cs +++ b/Mono.VisualC.Interop/ABI/Impl/VirtualOnlyAbi.cs @@ -1,3 +1,12 @@ +// +// Mono.VisualC.Interop.ABI.VirtualOnlyAbi.cs: A generalized C++ ABI that only supports virtual methods +// +// Author: +// Alexander Corrado (alexander.corrado@gmail.com) +// +// Copyright (C) 2010 Alexander Corrado +// + using System; using System.Reflection; using System.Reflection.Emit; @@ -10,8 +19,8 @@ namespace Mono.VisualC.Interop { public VirtualOnlyAbi (MakeVTableDelegate makeVTable, MemberFilter vtableOverrideFilter) { - this.makeVTableMethod = makeVTable; - this.vtableOverrideFilter = vtableOverrideFilter; + this.make_vtable_method = makeVTable; + this.vtable_override_filter = vtableOverrideFilter; } public VirtualOnlyAbi () { } diff --git a/Mono.VisualC.Interop/CppInstancePtr.cs b/Mono.VisualC.Interop/CppInstancePtr.cs index 5eb6681a..6eb13f1a 100644 --- a/Mono.VisualC.Interop/CppInstancePtr.cs +++ b/Mono.VisualC.Interop/CppInstancePtr.cs @@ -18,9 +18,10 @@ using Mono.VisualC.Interop.ABI; namespace Mono.VisualC.Interop { public struct CppInstancePtr : ICppObject { private IntPtr ptr; - private bool manageMemory; + private bool manage_memory; private static Dictionary implCache = new Dictionary (); + public static CppInstancePtr ForManagedObject (TWrapper managed) where Iface : ICppClassOverridable { @@ -59,14 +60,14 @@ namespace Mono.VisualC.Interop { IntPtr handlePtr = GetGCHandle (managedWrapper); Marshal.WriteIntPtr (ptr, nativeSize, handlePtr); - manageMemory = true; + manage_memory = true; } // Alloc a new C++ instance when there is no managed wrapper. internal CppInstancePtr (int nativeSize) { ptr = Marshal.AllocHGlobal (nativeSize); - manageMemory = true; + manage_memory = true; } // Get a CppInstancePtr for an existing C++ instance from an IntPtr @@ -76,7 +77,7 @@ namespace Mono.VisualC.Interop { throw new ArgumentOutOfRangeException ("native cannot be null pointer"); ptr = native; - manageMemory = false; + manage_memory = false; } // Provide casts to/from IntPtr: @@ -101,7 +102,7 @@ namespace Mono.VisualC.Interop { } public bool IsManagedAlloc { - get { return manageMemory; } + get { return manage_memory; } } internal static IntPtr GetGCHandle (object managedWrapper) @@ -125,11 +126,11 @@ namespace Mono.VisualC.Interop { // TODO: Free GCHandle? public void Dispose () { - if (manageMemory && ptr != IntPtr.Zero) + if (manage_memory && ptr != IntPtr.Zero) Marshal.FreeHGlobal (ptr); ptr = IntPtr.Zero; - manageMemory = false; + manage_memory = false; } } } diff --git a/Mono.VisualC.Interop/CppLibrary.cs b/Mono.VisualC.Interop/CppLibrary.cs index 2693d4fc..bd0b62c6 100644 --- a/Mono.VisualC.Interop/CppLibrary.cs +++ b/Mono.VisualC.Interop/CppLibrary.cs @@ -18,11 +18,8 @@ using System.Reflection.Emit; using Mono.VisualC.Interop.ABI; -namespace Mono.VisualC.Interop -{ - - public sealed class CppLibrary - { +namespace Mono.VisualC.Interop { + public sealed class CppLibrary { internal static AssemblyBuilder interopAssembly; internal static ModuleBuilder interopModule; diff --git a/Mono.VisualC.Interop/Mono.VisualC.Interop.csproj b/Mono.VisualC.Interop/Mono.VisualC.Interop.csproj index ae6d24f1..c91ee50f 100644 --- a/Mono.VisualC.Interop/Mono.VisualC.Interop.csproj +++ b/Mono.VisualC.Interop/Mono.VisualC.Interop.csproj @@ -29,23 +29,6 @@ false CPPInterop - - none - false - bin\Release - prompt - 4 - false - CPPInterop - - - full - false - bin\Mac - 4 - Mono.VisualC.Interop - true - diff --git a/Tests/CppInstancePtrTests.cs b/Tests/CppInstancePtrTests.cs new file mode 100644 index 00000000..c02f17eb --- /dev/null +++ b/Tests/CppInstancePtrTests.cs @@ -0,0 +1,22 @@ +// +// CppInstancePtrTests.cs: Test cases to exercise the CppInstancePtr +// +// Author: +// Alexander Corrado (alexander.corrado@gmail.com) +// +// Copyright (C) 2010 Alexander Corrado +// + +using System; +using NUnit.Framework; +namespace Tests { + [TestFixture] + public class CppInstancePtrTests : CPPTestLibBase { + + [Test] + public void TestCase () + { + } + } +} + diff --git a/Tests/Support/CPPTestLibBase.cs b/Tests/Support/CPPTestLibBase.cs new file mode 100644 index 00000000..f99297eb --- /dev/null +++ b/Tests/Support/CPPTestLibBase.cs @@ -0,0 +1,18 @@ +using System; +using NUnit.Framework; + +using Mono.VisualC.Interop; +using Mono.VisualC.Interop.ABI; + +namespace Tests { + public class CPPTestLibBase { + + protected CppLibrary CPPTestLib { get; private set; } + + protected CPPTestLibBase (CppAbi abi) + { + this.CPPTestLib = new CppLibrary ("CPPTestLib", abi); + } + } +} + diff --git a/CPPPOC/CSimpleClass.cs b/Tests/Support/CSimpleClass.cs similarity index 98% rename from CPPPOC/CSimpleClass.cs rename to Tests/Support/CSimpleClass.cs index a7bd05de..5e3e4699 100644 --- a/CPPPOC/CSimpleClass.cs +++ b/Tests/Support/CSimpleClass.cs @@ -22,7 +22,6 @@ namespace CPPPOC { void M1(CppInstancePtr ths, int x); [Virtual] void V1(CppInstancePtr ths, int x); void M2(CppInstancePtr ths, int x, int y); - [Virtual] void V2(CppInstancePtr ths); // a C++ field directly accessible to managed code CppField value {get;} diff --git a/CPPPOC/CPPPOC.csproj b/Tests/Tests.csproj similarity index 60% rename from CPPPOC/CPPPOC.csproj rename to Tests/Tests.csproj index 4e93b1c1..fb338db9 100644 --- a/CPPPOC/CPPPOC.csproj +++ b/Tests/Tests.csproj @@ -5,10 +5,10 @@ AnyCPU 8.0.50727 2.0 - {7F309FEA-3A3F-40B1-BBF9-A09796253202} - Exe - CPPPOC - CPPPOC + {3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8} + Library + Tests + Tests true @@ -18,7 +18,11 @@ DEBUG prompt 4 - true + + + + + none @@ -27,33 +31,14 @@ prompt 4 - - none - false - bin\Release - prompt - 4 - - - full - false - bin\Mac - 4 - true - + + - - {4A864586-93C5-4DC1-8A80-F094A88506D7} - Mono.VisualC.Interop - - - - - - + + @@ -61,4 +46,17 @@ + + + {B01E6282-144E-481A-8E1F-95F708DFBC2D} + CPPTestLib + + + {4A864586-93C5-4DC1-8A80-F094A88506D7} + Mono.VisualC.Interop + + + + + \ No newline at end of file