Browse Source

Created new Tests project, code clean up.

git-svn-id: https://mono-soc-2010.googlecode.com/svn/trunk/cppinterop@40 a470b8cb-0e6f-1642-1b45-71e107334c4b
pull/1/head
alexander.corrado 16 years ago
parent
commit
3a28e42da8
  1. 90
      CPPInterop.sln
  2. 29
      CPPPOC/AssemblyInfo.cs
  3. 49
      CPPPOC/Main.cs
  4. 66
      CPPTest/CPPTest.cpp
  5. 68
      CPPTest/CPPTest.cproj
  6. 47
      CPPTest/CPPTest.h
  7. 39
      CPPTestLib/CPPTestLib.cproj
  8. 86
      CPPTestLib/CSimpleClass.cpp
  9. 102
      Mono.VisualC.Interop/ABI/CppAbi.cs
  10. 22
      Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs
  11. 13
      Mono.VisualC.Interop/ABI/Impl/VirtualOnlyAbi.cs
  12. 15
      Mono.VisualC.Interop/CppInstancePtr.cs
  13. 7
      Mono.VisualC.Interop/CppLibrary.cs
  14. 17
      Mono.VisualC.Interop/Mono.VisualC.Interop.csproj
  15. 22
      Tests/CppInstancePtrTests.cs
  16. 18
      Tests/Support/CPPTestLibBase.cs
  17. 1
      Tests/Support/CSimpleClass.cs
  18. 54
      Tests/Tests.csproj

90
CPPInterop.sln

@ -1,45 +1,45 @@ @@ -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

29
CPPPOC/AssemblyInfo.cs

@ -1,29 +0,0 @@ @@ -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("")]

49
CPPPOC/Main.cs

@ -1,49 +0,0 @@ @@ -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);
}
}

66
CPPTest/CPPTest.cpp

@ -1,66 +0,0 @@ @@ -1,66 +0,0 @@
/*
* CPPTest.cpp
* CPPTest
*
* Created by Alex Corrado on 3/14/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <stdio.h>
#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);
}

68
CPPTest/CPPTest.cproj

@ -1,68 +0,0 @@ @@ -1,68 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B01E6282-144E-481A-8E1F-95F708DFBC2D}</ProjectGuid>
<Compiler>
<Compiler ctype="GccCompiler" />
</Compiler>
<Language>C</Language>
<Target>Bin</Target>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug</OutputPath>
<DefineSymbols>DEBUG MONODEVELOP</DefineSymbols>
<SourceDirectory>.</SourceDirectory>
<OutputName>CPPTest</OutputName>
<CompileTarget>SharedLibrary</CompileTarget>
<CustomCommands>
<CustomCommands>
<Command type="Build" command="echo Nothing to do" />
</CustomCommands>
</CustomCommands>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release</OutputPath>
<DefineSymbols>MONODEVELOP</DefineSymbols>
<SourceDirectory>.</SourceDirectory>
<OptimizationLevel>3</OptimizationLevel>
<OutputName>CPPTest</OutputName>
<CompileTarget>Bin</CompileTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Mac|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>build\Debug</OutputPath>
<ExtraLinkerArguments>-dynamic</ExtraLinkerArguments>
<DefineSymbols>DEBUG MONODEVELOP</DefineSymbols>
<SourceDirectory>.</SourceDirectory>
<CustomCommands>
<CustomCommands>
<Command type="Build" command="xcodebuild -configuration Debug" workingdir="${ProjectDir}" />
<Command type="AfterBuild" command="cp ./build/Debug/libCPPTest.dylib ../CPPPOC/bin/Mac" workingdir="${ProjectDir}" />
</CustomCommands>
</CustomCommands>
<OutputName>libCPPTest.dylib</OutputName>
<CompileTarget>Bin</CompileTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Linux|AnyCPU' ">
<OutputPath>build\Debug</OutputPath>
<DefineSymbols>DEBUG MONODEVELOP</DefineSymbols>
<CompileTarget>SharedLibrary</CompileTarget>
<OutputName>libCPPTest.so</OutputName>
<CustomCommands>
<CustomCommands>
<Command type="AfterBuild" command="cp ./build/Debug/libCPPTest.so ../CPPPOC/bin/Linux" workingdir="${ProjectDir}" />
</CustomCommands>
</CustomCommands>
</PropertyGroup>
<ItemGroup>
<None Include="CPPTest.h" />
</ItemGroup>
<ItemGroup>
<Compile Include="CPPTest.cpp" />
</ItemGroup>
</Project>

47
CPPTest/CPPTest.h

@ -1,47 +0,0 @@ @@ -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

39
CPPTestLib/CPPTestLib.cproj

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B01E6282-144E-481A-8E1F-95F708DFBC2D}</ProjectGuid>
<Compiler>
<Compiler ctype="GppCompiler" />
</Compiler>
<Language>CPP</Language>
<Target>Bin</Target>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug</OutputPath>
<DefineSymbols>DEBUG MONODEVELOP</DefineSymbols>
<SourceDirectory>.</SourceDirectory>
<OutputName>CPPTestLib</OutputName>
<CompileTarget>SharedLibrary</CompileTarget>
<CustomCommands>
<CustomCommands>
<Command type="AfterBuild" command="bash -c &quot;if [ `uname` = Darwin ]; then mv lib${ProjectName}.so lib${ProjectName}.dylib; fi&quot;" workingdir="${ProjectDir}/bin/Debug" />
</CustomCommands>
</CustomCommands>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release</OutputPath>
<DefineSymbols>MONODEVELOP</DefineSymbols>
<SourceDirectory>.</SourceDirectory>
<OptimizationLevel>3</OptimizationLevel>
<OutputName>CPPTest</OutputName>
<CompileTarget>Bin</CompileTarget>
</PropertyGroup>
<ItemGroup>
<Compile Include="CSimpleClass.cpp" />
</ItemGroup>
</Project>

86
CPPTestLib/CSimpleClass.cpp

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
/*
* CPPTest.cpp
* CPPTest
*
* Created by Alex Corrado on 3/14/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <stdio.h>
/* 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

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

@ -21,19 +21,19 @@ namespace Mono.VisualC.Interop.ABI { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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

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

@ -1,3 +1,11 @@ @@ -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; @@ -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 { @@ -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) {

13
Mono.VisualC.Interop/ABI/Impl/VirtualOnlyAbi.cs

@ -1,3 +1,12 @@ @@ -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 { @@ -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 () { }

15
Mono.VisualC.Interop/CppInstancePtr.cs

@ -18,9 +18,10 @@ using Mono.VisualC.Interop.ABI; @@ -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<Type,object> implCache = new Dictionary<Type,object> ();
public static CppInstancePtr ForManagedObject<Iface,TWrapper> (TWrapper managed)
where Iface : ICppClassOverridable<TWrapper>
{
@ -59,14 +60,14 @@ namespace Mono.VisualC.Interop { @@ -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 { @@ -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 { @@ -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 { @@ -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;
}
}
}

7
Mono.VisualC.Interop/CppLibrary.cs

@ -18,11 +18,8 @@ using System.Reflection.Emit; @@ -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;

17
Mono.VisualC.Interop/Mono.VisualC.Interop.csproj

@ -29,23 +29,6 @@ @@ -29,23 +29,6 @@
<ConsolePause>false</ConsolePause>
<AssemblyName>CPPInterop</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Linux|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<AssemblyName>CPPInterop</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Mac|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Mac</OutputPath>
<WarningLevel>4</WarningLevel>
<AssemblyName>Mono.VisualC.Interop</AssemblyName>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

22
Tests/CppInstancePtrTests.cs

@ -0,0 +1,22 @@ @@ -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 ()
{
}
}
}

18
Tests/Support/CPPTestLibBase.cs

@ -0,0 +1,18 @@ @@ -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);
}
}
}

1
CPPPOC/CSimpleClass.cs → Tests/Support/CSimpleClass.cs

@ -22,7 +22,6 @@ namespace CPPPOC { @@ -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<int> value {get;}

54
CPPPOC/CPPPOC.csproj → Tests/Tests.csproj

@ -5,10 +5,10 @@ @@ -5,10 +5,10 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7F309FEA-3A3F-40B1-BBF9-A09796253202}</ProjectGuid>
<OutputType>Exe</OutputType>
<AssemblyName>CPPPOC</AssemblyName>
<RootNamespace>CPPPOC</RootNamespace>
<ProjectGuid>{3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Tests</RootNamespace>
<AssemblyName>Tests</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -18,7 +18,11 @@ @@ -18,7 +18,11 @@
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<CustomCommands>
<CustomCommands>
<Command type="AfterBuild" command="bash -c &quot;if [ `uname` = Darwin ]; then cp CPPTestLib/bin/Debug/libCPPTestLib.dylib ${TargetDir}; fi&quot;" workingdir="${SolutionDir}" />
</CustomCommands>
</CustomCommands>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@ -27,33 +31,14 @@ @@ -27,33 +31,14 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Linux|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Mac|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Mac</OutputPath>
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="nunit.core, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77" />
<Reference Include="nunit.framework, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.VisualC.Interop\Mono.VisualC.Interop.csproj">
<Project>{4A864586-93C5-4DC1-8A80-F094A88506D7}</Project>
<Name>Mono.VisualC.Interop</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="CSimpleClass.cs" />
<Compile Include="CppInstancePtrTests.cs" />
<Compile Include="Support\CPPTestLibBase.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
@ -61,4 +46,17 @@ @@ -61,4 +46,17 @@
<Properties InternalTargetFrameworkVersion="3.5" />
</MonoDevelop>
</ProjectExtensions>
<ItemGroup>
<ProjectReference Include="..\CPPTestLib\CPPTestLib.cproj">
<Project>{B01E6282-144E-481A-8E1F-95F708DFBC2D}</Project>
<Name>CPPTestLib</Name>
</ProjectReference>
<ProjectReference Include="..\Mono.VisualC.Interop\Mono.VisualC.Interop.csproj">
<Project>{4A864586-93C5-4DC1-8A80-F094A88506D7}</Project>
<Name>Mono.VisualC.Interop</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Support\" />
</ItemGroup>
</Project>
Loading…
Cancel
Save