Browse Source

QtTest now pops up simple "Hello world!" window. Rudimentary support for

multiple inheritance. Automatic marshaling support for ICppObject with custom marshaler.
Improvements to name mangling for ItaniumAbi. Lots more TODOs.

git-svn-id: https://mono-soc-2010.googlecode.com/svn/trunk/cppinterop@50 a470b8cb-0e6f-1642-1b45-71e107334c4b
pull/1/head
alexander.corrado 16 years ago
parent
commit
7fd37ad3d7
  1. 59
      Mono.VisualC.Interop/ABI/CppAbi.cs
  2. 52
      Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs
  3. 2
      Mono.VisualC.Interop/ABI/VTable.cs
  4. 7
      Mono.VisualC.Interop/ABI/VTableCOM.cs
  5. 7
      Mono.VisualC.Interop/ABI/VTableManaged.cs
  6. 39
      Mono.VisualC.Interop/Attributes.cs
  7. 53
      Mono.VisualC.Interop/Util.cs
  8. 2
      QtBindings/AssemblyInfo.cs
  9. 37
      QtBindings/Core/QCoreApplication.cs
  10. 18
      QtBindings/Core/QObject.cs
  11. 18
      QtBindings/Core/QSize.cs
  12. 69
      QtBindings/Core/QString.cs
  13. 37
      QtBindings/Gui/QAbstractButton.cs
  14. 14
      QtBindings/Gui/QApplication.cs
  15. 50
      QtBindings/Gui/QPaintDevice.cs
  16. 49
      QtBindings/Gui/QPushButton.cs
  17. 111
      QtBindings/Gui/QWidget.cs
  18. 8
      QtBindings/QtBindings.csproj
  19. 1
      QtBindings/QtBindings.dll.config
  20. 13
      QtTest/Main.cs

59
Mono.VisualC.Interop/ABI/CppAbi.cs

@ -75,17 +75,10 @@ namespace Mono.VisualC.Interop.ABI { @@ -75,17 +75,10 @@ namespace Mono.VisualC.Interop.ABI {
);
// TODO: If a method in a base class interface is defined again in a child class
// interface with exactly the same signature, it will prolly share a vtable slot
// interface with exactly the same signature, it will prolly share a vtable slot?????
// first, pull in all virtual methods from base classes
var baseVirtualMethods = from iface in interface_type.GetInterfaces ()
where iface.Name.Equals ("Base`1")
from method in iface.GetGenericArguments ().First ().GetMethods ()
where Modifiers.IsVirtual (method)
orderby method.MetadataToken
select GetManagedOverrideTrampoline (method, vtable_override_filter);
var baseVirtualMethods = GetBaseVirtualMethods (interface_type);
var virtualMethods = baseVirtualMethods.Concat ( // now create managed overrides for virtuals in this class
from method in methods
where Modifiers.IsVirtual (method)
@ -93,7 +86,12 @@ namespace Mono.VisualC.Interop.ABI { @@ -93,7 +86,12 @@ namespace Mono.VisualC.Interop.ABI {
select GetManagedOverrideTrampoline (method, vtable_override_filter)
);
// ONLY make vtable if there are virtual methods
if (virtualMethods.Any ())
vtable = make_vtable_method (virtualMethods.ToArray ());
else
vtable = null;
int vtableIndex = baseVirtualMethods.Count ();
// Implement all methods
@ -116,6 +114,30 @@ namespace Mono.VisualC.Interop.ABI { @@ -116,6 +114,30 @@ namespace Mono.VisualC.Interop.ABI {
return (Iface)Activator.CreateInstance (impl_type.CreateType (), vtable, NativeSize);
}
protected virtual IEnumerable<Delegate> GetBaseVirtualMethods (Type searchStart)
{
var bases = from baseIface in searchStart.GetInterfaces ()
where baseIface.Name.Equals ("Base`1")
from iface in baseIface.GetGenericArguments ()
select iface;
List<Delegate> virtualMethods = new List<Delegate> ();
foreach (var iface in bases)
{
virtualMethods.AddRange (GetBaseVirtualMethods (iface));
var methods = from method in iface.GetMethods ()
where Modifiers.IsVirtual (method)
orderby method.MetadataToken
select GetManagedOverrideTrampoline (method, vtable_override_filter);
virtualMethods.AddRange (methods);
}
return virtualMethods;
}
// These methods might be more commonly overridden for a given C++ ABI:
public virtual MethodType GetMethodType (MethodInfo imethod)
@ -315,7 +337,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -315,7 +337,7 @@ namespace Mono.VisualC.Interop.ABI {
DynamicMethod trampolineIn = new DynamicMethod (wrapper_type.Name + "_" + interfaceMethod.Name + "_FromNative", interfaceMethod.ReturnType,
parameterTypes, typeof (CppInstancePtr).Module, true);
Util.ApplyMethodParameterAttributes (interfaceMethod, trampolineIn);
Util.ApplyMethodParameterAttributes (interfaceMethod, trampolineIn, true);
ILGenerator il = trampolineIn.GetILGenerator ();
// for static methods:
@ -365,7 +387,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -365,7 +387,7 @@ namespace Mono.VisualC.Interop.ABI {
Type[] parameterTypes = Util.GetMethodParameterTypes (interfaceMethod, false);
MethodBuilder methodBuilder = impl_type.DefineMethod (interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual,
interfaceMethod.ReturnType, parameterTypes);
Util.ApplyMethodParameterAttributes (interfaceMethod, methodBuilder);
Util.ApplyMethodParameterAttributes (interfaceMethod, methodBuilder, false);
return methodBuilder;
}
@ -384,8 +406,8 @@ namespace Mono.VisualC.Interop.ABI { @@ -384,8 +406,8 @@ namespace Mono.VisualC.Interop.ABI {
MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.PinvokeImpl,
CallingConventions.Any, signature.ReturnType, parameterTypes,
DefaultCallingConvention, CharSet.Ansi);
builder.SetImplementationFlags (builder.GetMethodImplementationFlags () | MethodImplAttributes.PreserveSig);
Util.ApplyMethodParameterAttributes (signature, builder, true);
return builder;
}
@ -533,19 +555,24 @@ namespace Mono.VisualC.Interop.ABI { @@ -533,19 +555,24 @@ namespace Mono.VisualC.Interop.ABI {
out LocalBuilder native)
{
cppip = null;
native = il.DeclareLocal (typeof (IntPtr));
native = null;
il.Emit (OpCodes.Ldarg_1);
if (firstParamType.Equals (typeof (CppInstancePtr))) {
cppip = il.DeclareLocal (typeof (CppInstancePtr));
native = il.DeclareLocal (typeof (IntPtr));
il.Emit (OpCodes.Stloc_S, cppip);
il.Emit (OpCodes.Ldloca_S, cppip);
il.Emit (OpCodes.Call, typeof (CppInstancePtr).GetProperty ("Native").GetGetMethod ());
il.Emit (OpCodes.Stloc_S, native);
} else if (firstParamType.Equals (typeof (IntPtr)))
} else if (firstParamType.Equals (typeof (IntPtr))) {
native = il.DeclareLocal (typeof (IntPtr));
il.Emit (OpCodes.Stloc_S, native);
else
throw new ArgumentException ("First argument to non-static C++ method must be IntPtr or CppInstancePtr.");
} else if (firstParamType.IsByRef) {
native = il.DeclareLocal (firstParamType);
il.Emit (OpCodes.Stloc_S, native);
} else
throw new ArgumentException ("First argument to non-static C++ method must be byref, IntPtr or CppInstancePtr.");
}
protected virtual void EmitCheckManagedAlloc (ILGenerator il, LocalBuilder cppip)

52
Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs

@ -31,59 +31,77 @@ namespace Mono.VisualC.Interop.ABI { @@ -31,59 +31,77 @@ namespace Mono.VisualC.Interop.ABI {
MethodType methodType = GetMethodType (methodInfo);
ParameterInfo[] parameters = methodInfo.GetParameters ();
StringBuilder nm = new StringBuilder("_ZN", 30);
nm.Append(class_name.Length).Append(class_name);
StringBuilder nm = new StringBuilder ("_ZN", 30);
nm.Append (class_name.Length).Append (class_name);
switch (methodType) {
case MethodType.NativeCtor:
nm.Append("C1");
nm.Append ("C1");
break;
case MethodType.NativeDtor:
nm.Append("D1");
nm.Append ("D1");
break;
default:
nm.Append(methodName.Length).Append(methodName);
nm.Append (methodName.Length).Append (methodName);
break;
}
nm.Append("E");
nm.Append ("E");
int argStart = (Modifiers.IsStatic (methodInfo)? 0 : 1);
if (parameters.Length == argStart) { // no args (other than C++ "this" object)
nm.Append("v");
nm.Append ("v");
} else for (int i = argStart; i < parameters.Length; i++) {
nm.Append(GetTypeCode(parameters[i]));
nm.Append (GetTypeCode (Modifiers.GetMangleInfo (parameters[i])));
}
return nm.ToString();
return nm.ToString ();
}
protected virtual string GetTypeCode(ParameterInfo param) {
protected virtual string GetTypeCode(MangleAsAttribute mangleInfo) {
Type type = Modifiers.GetMangleType (param);
Type type = mangleInfo.MangleType;
Type element = type;
bool cppObj = typeof (ICppObject).IsAssignableFrom (element);
StringBuilder code = new StringBuilder ();
if (type.IsByRef)
if (type.IsArray)
{
code.Append ("R");
code.Append ("P");
element = type.GetElementType ();
}
if (type.IsArray)
if (type.IsByRef)
{
code.Append ("P");
code.Append ("R");
element = type.GetElementType ();
}
else
if (mangleInfo.Modifiers == CppModifiers.PointerToConst)
code.Append ("PK");
else
if (cppObj || mangleInfo.Modifiers == CppModifiers.Pointer || mangleInfo.Modifiers == CppModifiers.ConstPointer)
code.Append ("P");
if (element.Equals (typeof (string)))
code.Append ("P");
if (mangleInfo.Modifiers == CppModifiers.Const)
code.Append ("K");
if (element.Equals (typeof (int))) code.Append ("i");
else if (element.Equals (typeof (string))) code.Append ("Pc"); // char *
else if (typeof (ICppObject).IsAssignableFrom (element)) { code.Append(element.Name.Length); code.Append(element.Name); }
else if (element.Equals (typeof (ushort))) code.Append ("t");
else if (element.Equals (typeof (string))) code.Append ("c"); // char
else if (cppObj || element.StructLayoutAttribute.Value != LayoutKind.Auto) {
code.Append(element.Name.Length);
code.Append(element.Name);
}
else throw new NotSupportedException ("Unsupported parameter type: " + type.ToString ());
return code.ToString ();

2
Mono.VisualC.Interop/ABI/VTable.cs

@ -17,7 +17,7 @@ using System.Runtime.InteropServices; @@ -17,7 +17,7 @@ using System.Runtime.InteropServices;
namespace Mono.VisualC.Interop.ABI {
public delegate VTable MakeVTableDelegate (Delegate[] overrides);
// TODO: RTTI
// TODO: RTTI .. support virtual inheritance
public abstract class VTable : IDisposable {
// The COM-interop-based implemenation is the default because it offers better

7
Mono.VisualC.Interop/ABI/VTableCOM.cs

@ -18,12 +18,7 @@ using System.Runtime.InteropServices; @@ -18,12 +18,7 @@ using System.Runtime.InteropServices;
namespace Mono.VisualC.Interop.ABI {
public class VTableCOM : VTable {
private static VTable MakeVTableCOM (Delegate[] entries)
{
return new VTableCOM (entries);
}
public static MakeVTableDelegate Implementation = MakeVTableCOM;
public static MakeVTableDelegate Implementation = (entries) => { return new VTableCOM (entries); };
private VTableCOM (Delegate[] entries) : base(entries)
{
int managedOverrides = (from entry in entries

7
Mono.VisualC.Interop/ABI/VTableManaged.cs

@ -18,12 +18,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -18,12 +18,7 @@ namespace Mono.VisualC.Interop.ABI {
public class VTableManaged : VTable {
private ModuleBuilder implModule;
private static VTable MakeVTableManaged (Delegate[] entries)
{
return new VTableManaged (entries);
}
public static MakeVTableDelegate Implementation = MakeVTableManaged;
public static MakeVTableDelegate Implementation = (entries) => { return new VTableManaged (entries); };
private VTableManaged (Delegate[] entries) : base(entries)
{
this.implModule = CppLibrary.interopModule;

39
Mono.VisualC.Interop/Attributes.cs

@ -18,20 +18,45 @@ namespace Mono.VisualC.Interop { @@ -18,20 +18,45 @@ namespace Mono.VisualC.Interop {
[AttributeUsage (AttributeTargets.Method)]
public class StaticAttribute : Attribute {}
[AttributeUsage (AttributeTargets.Parameter)]
public class ConstAttribute : Attribute {}
[AttributeUsage (AttributeTargets.Method)]
public class OverrideNativeAttribute : Attribute {}
[AttributeUsage (AttributeTargets.Parameter)]
public class MangleAsAttribute : Attribute {
public CppModifiers Modifiers { get; set; }
public Type MangleType { get; private set; }
public bool ByRef {
get { return MangleType.IsByRef; }
set {
if (!MangleType.IsByRef && value)
MangleType = MangleType.MakeByRefType ();
else if (MangleType.IsByRef && !value)
MangleType = MangleType.GetElementType ();
}
}
public MangleAsAttribute (Type mangleType)
{
this.Modifiers = CppModifiers.None;
this.MangleType = mangleType;
}
public MangleAsAttribute (string mangleTypeAsString)
public MangleAsAttribute (string mangleTypeStr)
{
this.MangleType = Type.GetType (mangleTypeAsString);
this.Modifiers = CppModifiers.None;
this.MangleType = Type.GetType (mangleTypeStr);
}
}
public enum CppModifiers {
None,
Const,
Pointer,
PointerToConst,
ConstPointer,
ConstPointerToConst
}
public static class Modifiers {
@ -46,13 +71,17 @@ namespace Mono.VisualC.Interop { @@ -46,13 +71,17 @@ namespace Mono.VisualC.Interop {
return method.IsDefined (typeof (StaticAttribute), false);
}
public static Type GetMangleType (ParameterInfo param)
public static MangleAsAttribute GetMangleInfo (ParameterInfo param)
{
MangleAsAttribute maa = (MangleAsAttribute)param.GetCustomAttributes (typeof (MangleAsAttribute), false).FirstOrDefault ();
bool isConst = param.IsDefined (typeof (ConstAttribute), false);
if (maa == null)
return param.ParameterType;
maa = new MangleAsAttribute (param.ParameterType);
if (isConst)
maa.Modifiers = CppModifiers.Const;
return maa.MangleType;
return maa;
}
}
}

53
Mono.VisualC.Interop/Util.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Reflection.Emit;
@ -70,18 +72,57 @@ namespace Mono.VisualC.Interop { @@ -70,18 +72,57 @@ namespace Mono.VisualC.Interop {
return parameterTypes;
}
public static void ApplyMethodParameterAttributes (MethodInfo source, MethodBuilder target)
public static void ApplyMethodParameterAttributes (MethodInfo source, MethodBuilder target, bool forPInvoke)
{
ParameterInfo[] parameters = source.GetParameters ();
foreach (var parameter in parameters)
target.DefineParameter (parameter.Position, parameter.Attributes, parameter.Name);
foreach (var param in parameters)
ApplyAttributes (param, target.DefineParameter, forPInvoke);
}
public static void ApplyMethodParameterAttributes (MethodInfo source, DynamicMethod target)
public static void ApplyMethodParameterAttributes (MethodInfo source, DynamicMethod target, bool forPInvoke)
{
ParameterInfo[] parameters = source.GetParameters ();
foreach (var parameter in parameters)
target.DefineParameter (parameter.Position, parameter.Attributes, parameter.Name);
foreach (var param in parameters)
ApplyAttributes (param, target.DefineParameter, forPInvoke);
}
public static ParameterBuilder ApplyAttributes (ParameterInfo param, Func<int,ParameterAttributes,string,ParameterBuilder> makePB, bool forPInvoke)
{
ParameterAttributes attr = param.Attributes;
CustomAttributeBuilder marshalAsAttr = null;
MarshalAsAttribute existingMarshalAs = param.GetCustomAttributes (typeof (MarshalAsAttribute),
false).FirstOrDefault () as MarshalAsAttribute;
if (forPInvoke && typeof (ICppObject).IsAssignableFrom (param.ParameterType) &&
!param.ParameterType.Equals (typeof (CppInstancePtr)) && existingMarshalAs == null)
{
ConstructorInfo ctor = typeof (MarshalAsAttribute).GetConstructor (new Type[] { typeof (UnmanagedType) });
object[] args = new object [] { UnmanagedType.CustomMarshaler };
FieldInfo[] fields = new FieldInfo [] { typeof (MarshalAsAttribute).GetField("MarshalTypeRef") };
object[] values = new object [] { typeof (CppObjectMarshaler) };
marshalAsAttr = new CustomAttributeBuilder (ctor, args, fields, values);
attr = attr | ParameterAttributes.HasFieldMarshal;
} else if (forPInvoke && existingMarshalAs != null) {
// TODO: This still doesn't feel like it's working right..
ConstructorInfo ctor = typeof (MarshalAsAttribute).GetConstructor (new Type[] { typeof (UnmanagedType) });
object[] args = new object [] { existingMarshalAs.Value };
var fields = from field in typeof (MarshalAsAttribute).GetFields ()
where field.GetValue (existingMarshalAs) != null
select field;
var values = from field in fields select field.GetValue (existingMarshalAs);
marshalAsAttr = new CustomAttributeBuilder (ctor, args, fields.ToArray (), values.ToArray ());
attr = attr | ParameterAttributes.HasFieldMarshal;
}
ParameterBuilder pb = makePB (param.Position, attr, param.Name);
if (marshalAsAttr != null) pb.SetCustomAttribute (marshalAsAttr);
return pb;
}
}
}

2
QtBindings/AssemblyInfo.cs

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
@ -18,6 +19,7 @@ using System.Runtime.CompilerServices; @@ -18,6 +19,7 @@ using System.Runtime.CompilerServices;
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
[assembly: CLSCompliant(true)]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.

37
QtBindings/Core/QCoreApplication.cs

@ -7,6 +7,7 @@ namespace Qt.Core { @@ -7,6 +7,7 @@ namespace Qt.Core {
#region Sync with qcoreapplication.h
// C++ interface
protected interface IQCoreApplication : ICppClassOverridable<QCoreApplication>, Base<QObject.IQObject> {
// ...
void QCoreApplication (CppInstancePtr @this, [MangleAs ("System.Int32&")] IntPtr argc,
[MangleAs (typeof (string[]))] IntPtr argv);
// ...
@ -21,33 +22,17 @@ namespace Qt.Core { @@ -21,33 +22,17 @@ namespace Qt.Core {
#endregion
private static IQCoreApplication impl = Qt.Libs.QtCore.GetClass<IQCoreApplication,_QCoreApplication,QCoreApplication> ("QCoreApplication");
protected IntPtr argc;
protected IntPtr argv;
public QCoreApplication () : this (true)
public QCoreApplication () : base (IntPtr.Zero)
{
this.native = impl.Alloc (this);
InitArgcAndArgv ();
impl.QCoreApplication (native, argc, argv);
}
protected QCoreApplication (bool foo) : base (IntPtr.Zero)
{
// for some reason, this includes arg0, but the args passed to Main (string[]) do not!
string[] args = Environment.GetCommandLineArgs ();
int argCount = args.Length;
argc = Marshal.AllocHGlobal (sizeof (int));
Marshal.WriteInt32 (argc, argCount);
argv = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (IntPtr)) * argCount);
for (var i = 0; i < argCount; i++) {
IntPtr arg = Marshal.StringToHGlobalAnsi (args [i]);
Marshal.WriteIntPtr (argv, i * Marshal.SizeOf (typeof (IntPtr)), arg);
}
}
public QCoreApplication (IntPtr native) : base (native)
{
}
@ -71,6 +56,22 @@ namespace Qt.Core { @@ -71,6 +56,22 @@ namespace Qt.Core {
native.Dispose ();
}
protected void InitArgcAndArgv ()
{
// for some reason, this includes arg0, but the args passed to Main (string[]) do not!
string[] args = Environment.GetCommandLineArgs ();
int argCount = args.Length;
argc = Marshal.AllocHGlobal (sizeof (int));
Marshal.WriteInt32 (argc, argCount);
argv = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (IntPtr)) * argCount);
for (var i = 0; i < argCount; i++) {
IntPtr arg = Marshal.StringToHGlobalAnsi (args [i]);
Marshal.WriteIntPtr (argv, i * Marshal.SizeOf (typeof (IntPtr)), arg);
}
}
protected void FreeArgcAndArgv ()
{
Marshal.FreeHGlobal (argc);

18
QtBindings/Core/QObject.cs

@ -6,8 +6,14 @@ namespace Qt.Core { @@ -6,8 +6,14 @@ namespace Qt.Core {
public class QObject : ICppObject {
#region Sync with qobject.h
// C++ interface
protected interface IQObject : ICppClassOverridable<QObject> {
void QObject (CppInstancePtr @this, [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof (CppObjectMarshaler))] QObject parent);
public interface IQObject : ICppClassOverridable<QObject> {
// ...
[Virtual] /*QMetaObject */ IntPtr metaObject(CppInstancePtr @this);
[Virtual] /*void */ IntPtr qt_metacast(CppInstancePtr @this, string s);
[Virtual] int qt_metacall(CppInstancePtr @this, /*QMetaObject::Call */ int qMetaObjectCall, int x, /*void **/ IntPtr p);
// ...
void QObject (CppInstancePtr @this, QObject parent);
// ...
[Virtual] bool @event (CppInstancePtr @this, IntPtr qEvent);
[Virtual] bool eventFilter (CppInstancePtr @this, IntPtr qObject, IntPtr qEvent);
[Virtual] void timerEvent (CppInstancePtr @this, IntPtr qTimerEvent);
@ -25,16 +31,14 @@ namespace Qt.Core { @@ -25,16 +31,14 @@ namespace Qt.Core {
private static IQObject impl = Qt.Libs.QtCore.GetClass<IQObject,_QObject,QObject> ("QObject");
protected CppInstancePtr native;
public QObject ()
public QObject (QObject parent)
{
native = impl.Alloc (this);
impl.QObject (native, null);
impl.QObject (native, parent);
}
public QObject (QObject parent)
public QObject () : this (null)
{
native = impl.Alloc (this);
impl.QObject (native, parent);
}
public QObject (IntPtr native)

18
QtBindings/Core/QSize.cs

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
using System;
using System.Runtime.InteropServices;
using Mono.VisualC.Interop;
namespace Qt.Core {
[StructLayout (LayoutKind.Sequential)]
public struct QSize {
public int wd;
public int ht;
public QSize (int w, int h)
{
this.wd = w;
this.ht = h;
}
}
}

69
QtBindings/Core/QString.cs

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
using System;
using System.Text;
using System.Runtime.InteropServices;
using Mono.VisualC.Interop;
namespace Qt.Core {
//TODO: Will this leak?
[StructLayout (LayoutKind.Sequential)]
public unsafe struct QString {
#region Sync with qstring.h
public interface IQString : ICppClass {
void QString(ref QString @this,
[MangleAs (typeof (QChar), Modifiers=CppModifiers.PointerToConst)]
IntPtr unicode, int size);
}
[StructLayout (LayoutKind.Sequential)]
private struct QChar {}
[StructLayout (LayoutKind.Sequential)]
public struct Data {
public int @ref;
public int alloc, size;
public IntPtr data;
public ushort clean;
public ushort simpletext;
public ushort righttoleft;
public ushort asciiCache;
public ushort capacity;
public ushort reserved;
public IntPtr array;
}
public Data* d;
#endregion
private static IQString impl = Qt.Libs.QtCore.GetClass<IQString> ("QString");
public QString (string str)
{
IntPtr strPtr = Marshal.StringToHGlobalUni (str);
impl.QString (ref this, strPtr, str.Length);
Marshal.FreeHGlobal (strPtr);
// TODO: I deref this on construction to let Qt free it when it's done with it.
// My assumption is that this struct will only be used to interop with Qt and
// no managed class is going to hold on to it.
this.DeRef ();
}
public static implicit operator QString (string str)
{
return new QString (str);
}
public QString AddRef ()
{
d->@ref++;
return this;
}
public QString DeRef ()
{
d->@ref--;
return this;
}
}
}

37
QtBindings/Gui/QAbstractButton.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
using System;
using Mono.VisualC.Interop;
namespace Qt.Gui {
public class QAbstractButton : QWidget {
#region Sync with qabstractbutton.h
// C++ interface
public interface IQAbstractButton : ICppClassOverridable<QAbstractButton>, Base<QWidget.IQWidget> {
// ...
void QAbstractButton (CppInstancePtr @this, QWidget parent);
// ...
[Virtual] void paintEvent (CppInstancePtr @this, /*QPaintEvent */ IntPtr e); // abstract
[Virtual] bool hitButton (CppInstancePtr @this, /*const QPoint &*/ IntPtr pos);
[Virtual] void checkStateSet (CppInstancePtr @this);
[Virtual] void nextCheckState (CppInstancePtr @this);
}
private struct _QAbstractButton {
}
#endregion
public QAbstractButton (IntPtr native) : base (native)
{
}
/*
public override int NativeSize {
get { return impl.NativeSize + base.NativeSize; }
}
*/
public override void Dispose ()
{
throw new Exception ("This should never be called!");
}
}
}

14
QtBindings/Gui/QApplication.cs

@ -9,14 +9,25 @@ namespace Qt.Gui { @@ -9,14 +9,25 @@ namespace Qt.Gui {
#region Sync with qapplication.h
// C++ interface
protected interface IQApplication : ICppClassOverridable<QApplication>, Base<QCoreApplication.IQCoreApplication> {
// ...
void QApplication (CppInstancePtr @this, [MangleAs ("System.Int32&")] IntPtr argc,
[MangleAs (typeof (string[]))] IntPtr argv, int version);
// ...
[Virtual] bool macEventFilter(CppInstancePtr @this, IntPtr eventHandlerCallRef, IntPtr eventRef);
// ...
[Virtual] void commitData(CppInstancePtr @this, IntPtr qSessionManager); // was QSessionManager&
[Virtual] void saveState(CppInstancePtr @this, IntPtr qSessionManager); // was QSessionManager&
// ...
[Static] int exec ();
// TODO: HACK! Yeah... I'm not calculating the right number of vtable slots somewhere...
// ... add dummy methods until I figure it out...
[Virtual] void foo1 (CppInstancePtr @this);
[Virtual] void foo2 (CppInstancePtr @this);
[Virtual] void foo3 (CppInstancePtr @this);
[Virtual] void foo4 (CppInstancePtr @this);
[Virtual] void foo5 (CppInstancePtr @this);
[Virtual] void foo6 (CppInstancePtr @this);
}
// C++ fields
private struct _QApplication {
@ -25,9 +36,10 @@ namespace Qt.Gui { @@ -25,9 +36,10 @@ namespace Qt.Gui {
private static IQApplication impl = Qt.Libs.QtGui.GetClass<IQApplication,_QApplication,QApplication> ("QApplication");
public QApplication () : base (true)
public QApplication () : base (IntPtr.Zero)
{
this.native = impl.Alloc (this);
InitArgcAndArgv ();
impl.QApplication (native, argc, argv, QGlobal.QT_VERSION);
}

50
QtBindings/Gui/QPaintDevice.cs

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
using System;
using Mono.VisualC.Interop;
namespace Qt.Gui {
public class QPaintDevice : ICppObject {
#region Sync with qpaintdevice.h
// C++ interface
public interface IQPaintDevice : ICppClassOverridable<QPaintDevice> {
[Virtual] int devType (CppInstancePtr @this);
[Virtual] /*QPaintEngine */ IntPtr paintEngine (CppInstancePtr @this); // abstract
//...
void QPaintDevice (CppInstancePtr @this);
[Virtual] int metric (CppInstancePtr @this, /*PaintDeviceMetric*/ IntPtr metric);
}
// C++ fields
private struct _QPaintDevice {
public ushort painters;
}
#endregion
private static IQPaintDevice impl = Qt.Libs.QtGui.GetClass<IQPaintDevice,_QPaintDevice,QPaintDevice> ("QPaintDevice");
protected CppInstancePtr native;
/* no point to this - subclasses will call QPaintDevice (IntPtr.Zero)
protected QPaintDevice ()
{
}
*/
public QPaintDevice (IntPtr native)
{
this.native = native;
}
public IntPtr Native {
get { return (IntPtr)native; }
}
public virtual int NativeSize {
get { return impl.NativeSize; }
}
public void Dispose ()
{
throw new Exception ("This should never be called!");
}
}
}

49
QtBindings/Gui/QPushButton.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
using System;
using Mono.VisualC.Interop;
using Qt.Core;
namespace Qt.Gui {
public class QPushButton : QAbstractButton {
#region Sync with qpushbutton.h
// C++ interface
public interface IQPushButton : ICppClassOverridable<QPushButton>, Base<QAbstractButton.IQAbstractButton> {
// ...
void QPushButton (CppInstancePtr @this, [Const] ref QString text,
QWidget parent);
// ...
}
// C++ fields
private struct _QPushButton {
}
#endregion
private IQPushButton impl = Qt.Libs.QtGui.GetClass<IQPushButton,_QPushButton,QPushButton> ("QPushButton");
public QPushButton (string btnText, QWidget parent) : base (IntPtr.Zero)
{
this.native = impl.Alloc (this);
QString text = btnText;
impl.QPushButton (native, ref text, parent);
}
public QPushButton (string text) : this (text, null)
{
}
public QPushButton (IntPtr native) : base (native)
{
}
public override int NativeSize {
get { return impl.NativeSize + base.NativeSize; }
}
public override void Dispose ()
{
impl.Destruct (native);
native.Dispose ();
}
}
}

111
QtBindings/Gui/QWidget.cs

@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
using System;
using System.Runtime.InteropServices;
using Mono.VisualC.Interop;
using Qt.Core;
namespace Qt.Gui {
public class QWidget : QObject {
#region Sync with qwidget.h
// C++ interface
public interface IQWidget : ICppClassOverridable<QWidget>, Base<QObject.IQObject>, Base<QPaintDevice.IQPaintDevice> {
// ...
void QWidget (CppInstancePtr @this, QWidget parent, /*Qt::WindowFlags */ int f);
// ...
[Virtual] void setVisible (CppInstancePtr @this, bool visible);
// ...
void resize (CppInstancePtr @this, [MangleAs (typeof (QSize), ByRef=true, Modifiers=CppModifiers.Const)] ref QSize size);
// ...
[Virtual] /*QSize*/ int sizeHint (CppInstancePtr @this);
[Virtual] /*QSize*/ int minimumSizeHint (CppInstancePtr @this);
// ...
[Virtual] int heightForWidth (CppInstancePtr @this, int width);
// ... protected:
[Virtual] void mousePressEvent (CppInstancePtr @this, /*QMouseEvent */ IntPtr p);
[Virtual] void mouseReleaseEvent (CppInstancePtr @this, /*QMouseEvent */ IntPtr p);
[Virtual] void mouseDoubleClickEvent (CppInstancePtr @this, /*QMouseEvent */ IntPtr p);
[Virtual] void mouseMoveEvent (CppInstancePtr @this, /*QMouseEvent */ IntPtr p);
[Virtual] void wheelEvent (CppInstancePtr @this, /*QWheelEvent */ IntPtr p);
[Virtual] void keyPressEvent (CppInstancePtr @this, /*QKeyEvent */ IntPtr p);
[Virtual] void keyReleaseEvent (CppInstancePtr @this, /*QKeyEvent */ IntPtr p);
[Virtual] void focusInEvent (CppInstancePtr @this, /*QFocusEvent */ IntPtr p);
[Virtual] void focusOutEvent (CppInstancePtr @this, /*QFocusEvent */ IntPtr p);
[Virtual] void enterEvent (CppInstancePtr @this, /*QEvent */ IntPtr p);
[Virtual] void leaveEvent (CppInstancePtr @this, /*QEvent */ IntPtr p);
[Virtual] void paintEvent (CppInstancePtr @this, /*QPaintEvent */ IntPtr p);
[Virtual] void moveEvent (CppInstancePtr @this, /*QMoveEvent */ IntPtr p);
[Virtual] void resizeEvent (CppInstancePtr @this, /*QResizeEvent */ IntPtr p);
[Virtual] void closeEvent (CppInstancePtr @this, /*QCloseEvent */ IntPtr p);
[Virtual] void contextMenuEvent (CppInstancePtr @this, /*QContextMenuEvent */ IntPtr p);
[Virtual] void tabletEvent (CppInstancePtr @this, /*QTabletEvent */ IntPtr p);
[Virtual] void actionEvent (CppInstancePtr @this, /*QActionEvent */ IntPtr p);
[Virtual] void dragEnterEvent (CppInstancePtr @this, /*QDragEnterEvent */ IntPtr p);
[Virtual] void dragMoveEvent (CppInstancePtr @this, /*QDragMoveEvent */ IntPtr p);
[Virtual] void dragLeaveEvent (CppInstancePtr @this, /*QDragLeaveEvent */ IntPtr p);
[Virtual] void dropEvent (CppInstancePtr @this, /*QDropEvent */ IntPtr p);
[Virtual] void showEvent (CppInstancePtr @this, /*QShowEvent */ IntPtr p);
[Virtual] void hideEvent (CppInstancePtr @this, /*QHideEvent */ IntPtr p);
[Virtual] bool macEvent (CppInstancePtr @this, /*EventHandlerCallRef */ IntPtr p1, /*EventRef */ IntPtr p2);
[Virtual] void changeEvent (CppInstancePtr @this, /*QEvent */ IntPtr p);
// ...
[Virtual] void inputMethodEvent (CppInstancePtr @this, /*QInputMethodEvent */ IntPtr p);
//public:
[Virtual] /*QVariant*/ IntPtr inputMethodQuery (CppInstancePtr @this, /*Qt::InputMethodQuery */ int x);
// ... protected:
[Virtual] bool focusNextPrevChild (CppInstancePtr @this, bool next);
// TODO: Determine correct number of vtable slots here too...
[Virtual] void foo1 (CppInstancePtr @this);
[Virtual] void foo2 (CppInstancePtr @this);
[Virtual] void foo3 (CppInstancePtr @this);
[Virtual] void foo4 (CppInstancePtr @this);
[Virtual] void foo5 (CppInstancePtr @this);
[Virtual] void foo6 (CppInstancePtr @this);
[Virtual] void foo7 (CppInstancePtr @this);
[Virtual] void foo8 (CppInstancePtr @this);
}
// C++ fields
private struct _QWidget {
public IntPtr data;
}
#endregion
private static IQWidget impl = Qt.Libs.QtGui.GetClass<IQWidget,_QWidget,QWidget> ("QWidget");
// TODO: ctor ...
public QWidget (IntPtr native) : base (native)
{
}
public bool Visible {
get {
throw new NotImplementedException ();
}
set {
impl.setVisible (native, value);
}
}
public void Resize (int width, int height)
{
QSize s = new QSize (width, height);
impl.resize (native, ref s);
}
// TODO: HELP! I think this really should be:
// sizeof(QWidget) [impl.NativeSize] + sizeof(QObject) [base.NativeSize] + sizeof(QPaintDevice) [????]
// Works for now because we're already alloc'ing too much memory!!? (NativeSize property contains vtbl pointer)
public override int NativeSize {
get { return impl.NativeSize + base.NativeSize; }
}
public override void Dispose ()
{
throw new NotImplementedException ();
}
}
}

8
QtBindings/QtBindings.csproj

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@ -27,6 +28,7 @@ @@ -27,6 +28,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -38,6 +40,12 @@ @@ -38,6 +40,12 @@
<Compile Include="Core\QGlobal.cs" />
<Compile Include="Core\QCoreApplication.cs" />
<Compile Include="Core\QObject.cs" />
<Compile Include="Gui\QPushButton.cs" />
<Compile Include="Gui\QPaintDevice.cs" />
<Compile Include="Gui\QWidget.cs" />
<Compile Include="Gui\QAbstractButton.cs" />
<Compile Include="Core\QString.cs" />
<Compile Include="Core\QSize.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.VisualC.Interop\Mono.VisualC.Interop.csproj">

1
QtBindings/QtBindings.dll.config

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
<!-- The dllmap doesn't work (I think) because the assembly that actually has the DllImports is the one emitted by SRE -->
<configuration>
<dllmap dll="QtCore4" os="osx" target="/Library/Frameworks/QtCore.framework/Versions/Current/QtCore" />
<dllmap dll="QtGui4" os="osx" target="/Library/Frameworks/QtGui.framework/Versions/Current/QtGui" />

13
QtTest/Main.cs

@ -1,14 +1,19 @@ @@ -1,14 +1,19 @@
using System;
using Qt.Core;
using Qt.Gui;
namespace QtTest {
class MainClass {
public static int Main (string[] args)
public static void Main (string[] args)
{
using (QCoreApplication app = new QCoreApplication ()) {
using (QApplication app = new QApplication ()) {
using (QPushButton hello = new QPushButton ("Hello world!")) {
return app.Exec ();
hello.Resize (100, 30);
hello.Visible = true;
app.Exec ();
}
}
}
}

Loading…
Cancel
Save