[objc] Simpler generator that, so far, only handle static properties (#29)
The ObjC syntax for properties match the proposal from PR #25 [1]. Unit tests added for the matching features. [1] https://github.com/mono/Embeddinator-4000/pull/25
This commit is contained in:
Родитель
ca77db338c
Коммит
5cc5ea587d
|
@ -11,6 +11,7 @@ missing
|
|||
*.dll
|
||||
*.exe
|
||||
bin/
|
||||
obj/
|
||||
*.userprefs
|
||||
*.pc
|
||||
.DS_Store
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "objcgen", "objcgen\objcgen.csproj", "{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{21776062-DBDA-4408-BF22-9DCB2682DCBC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "objcgentest", "tests\objcgentest\objcgentest.csproj", "{076A871B-0C13-47D8-8923-B9242995BFF8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "managed", "tests\managed\managed.csproj", "{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}.Debug|x86.Build.0 = Debug|x86
|
||||
{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}.Release|x86.ActiveCfg = Release|x86
|
||||
{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}.Release|x86.Build.0 = Release|x86
|
||||
{076A871B-0C13-47D8-8923-B9242995BFF8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{076A871B-0C13-47D8-8923-B9242995BFF8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{076A871B-0C13-47D8-8923-B9242995BFF8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{076A871B-0C13-47D8-8923-B9242995BFF8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{076A871B-0C13-47D8-8923-B9242995BFF8} = {21776062-DBDA-4408-BF22-9DCB2682DCBC}
|
||||
{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903} = {21776062-DBDA-4408-BF22-9DCB2682DCBC}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using ObjC;
|
||||
|
||||
namespace Embeddinator {
|
||||
|
||||
static class Driver {
|
||||
|
||||
// TODO: use Mono.Options
|
||||
// TODO: add errors.cs
|
||||
public static int Main (string [] args)
|
||||
{
|
||||
bool shared = true; // dylib
|
||||
|
||||
Console.WriteLine ("Parsing assemblies...");
|
||||
|
||||
var assemblies = new List<Assembly> ();
|
||||
foreach (var arg in args) {
|
||||
assemblies.Add (Assembly.LoadFile (arg));
|
||||
Console.WriteLine ($"\tParsed '{arg}'");
|
||||
}
|
||||
|
||||
// by default the first specified assembly
|
||||
var name = Path.GetFileNameWithoutExtension (args [0]);
|
||||
|
||||
Console.WriteLine ("Processing assemblies...");
|
||||
var g = new ObjCGenerator ();
|
||||
g.Process (assemblies);
|
||||
|
||||
Console.WriteLine ("Generating binding code...");
|
||||
g.Generate (assemblies);
|
||||
g.Write ();
|
||||
|
||||
var exe = typeof (Driver).Assembly;
|
||||
foreach (var res in exe.GetManifestResourceNames ()) {
|
||||
if (res == "main.c") {
|
||||
// no main is needed for dylib and don't re-write an existing main.c file - it's a template
|
||||
if (shared || File.Exists ("main.c"))
|
||||
continue;
|
||||
}
|
||||
Console.WriteLine ($"\tGenerated: {res}");
|
||||
using (var sw = new StreamWriter (res))
|
||||
exe.GetManifestResourceStream (res).CopyTo (sw.BaseStream);
|
||||
}
|
||||
|
||||
Console.WriteLine ("Compiling binding code...");
|
||||
|
||||
StringBuilder options = new StringBuilder ("clang ");
|
||||
options.Append ("-DMONO_EMBEDDINATOR_DLL_EXPORT ");
|
||||
options.Append ("-framework CoreFoundation ");
|
||||
options.Append ("-I\"/Library/Frameworks/Mono.framework/Versions/Current/include/mono-2.0\" -L\"/Library/Frameworks/Mono.framework/Versions/Current/lib/\" -lmonosgen-2.0 ");
|
||||
options.Append ("glib.c mono_embeddinator.c bindings.m ");
|
||||
if (shared)
|
||||
options.Append ($"-dynamiclib -install_name lib{name}.dylib ");
|
||||
else
|
||||
options.Append ("main.c ");
|
||||
options.Append ($"-o lib{name}.dylib -ObjC -lobjc");
|
||||
|
||||
Console.WriteLine ("Compiling binding code...");
|
||||
Console.WriteLine ($"\tInvoking: xcrun {options}");
|
||||
var p = Process.Start ("xcrun", options.ToString ());
|
||||
p.WaitForExit ();
|
||||
Console.WriteLine ("Done");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Embeddinator {
|
||||
|
||||
public class Generator {
|
||||
|
||||
public virtual void Process (IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Generate (IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
foreach (var a in assemblies) {
|
||||
Generate (a);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Generate (Assembly a)
|
||||
{
|
||||
foreach (var t in a.GetTypes ()) {
|
||||
if (!t.IsPublic)
|
||||
continue;
|
||||
Generate (t);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Generate (Type t)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void Generate (PropertyInfo pi)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Write ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>objcgen</RootNamespace>
|
||||
<AssemblyName>objcgen</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Mono.Options">
|
||||
<HintPath>..\packages\Mono.Options.4.4.0.0\lib\net4-client\Mono.Options.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="generator.cs" />
|
||||
<Compile Include="objcgenerator.cs" />
|
||||
<Compile Include="driver.cs">
|
||||
<LogicalName>main.c</LogicalName>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="support\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\support\glib.c">
|
||||
<Link>support\glib.c</Link>
|
||||
<LogicalName>glib.c</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\support\glib.h">
|
||||
<Link>support\glib.h</Link>
|
||||
<LogicalName>glib.h</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\support\mono_embeddinator.c">
|
||||
<Link>support\mono_embeddinator.c</Link>
|
||||
<LogicalName>mono_embeddinator.c</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\support\mono_embeddinator.h">
|
||||
<Link>support\mono_embeddinator.h</Link>
|
||||
<LogicalName>mono_embeddinator.h</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\support\main.c">
|
||||
<Link>support\main.c</Link>
|
||||
<LogicalName>main.c</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,247 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
// TODO: bad, need to choose either IKVM.Reflection or Cecil
|
||||
using System.Reflection;
|
||||
|
||||
using Embeddinator;
|
||||
|
||||
namespace ObjC {
|
||||
|
||||
public class ObjCGenerator : Generator {
|
||||
|
||||
static TextWriter headers = new StringWriter ();
|
||||
static TextWriter implementation = new StringWriter ();
|
||||
|
||||
List<Type> types = new List<Type> ();
|
||||
|
||||
public override void Process (IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
foreach (var a in assemblies) {
|
||||
foreach (var t in a.GetTypes ()) {
|
||||
if (!t.IsPublic)
|
||||
continue;
|
||||
// gather types for forward declarations
|
||||
types.Add (t);
|
||||
}
|
||||
}
|
||||
Console.WriteLine ($"\t{types.Count} types found");
|
||||
}
|
||||
|
||||
public override void Generate (IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
headers.WriteLine ("#include \"mono_embeddinator.h\"");
|
||||
headers.WriteLine ("#import <Foundation/Foundation.h>");
|
||||
headers.WriteLine ();
|
||||
headers.WriteLine ("MONO_EMBEDDINATOR_BEGIN_DECLS");
|
||||
headers.WriteLine ();
|
||||
|
||||
headers.WriteLine ("// forward declarations");
|
||||
foreach (var t in types)
|
||||
headers.WriteLine ($"@class {GetTypeName (t)};");
|
||||
headers.WriteLine ();
|
||||
|
||||
implementation.WriteLine ("#include \"bindings.h\"");
|
||||
implementation.WriteLine ("#include \"glib.h\"");
|
||||
implementation.WriteLine ("#include <mono/jit/jit.h>");
|
||||
implementation.WriteLine ("#include <mono/metadata/assembly.h>");
|
||||
implementation.WriteLine ("#include <mono/metadata/object.h>");
|
||||
implementation.WriteLine ("#include <mono/metadata/mono-config.h>");
|
||||
implementation.WriteLine ("#include <mono/metadata/debug-helpers.h>");
|
||||
implementation.WriteLine ();
|
||||
|
||||
implementation.WriteLine ("mono_embeddinator_context_t __mono_context;");
|
||||
implementation.WriteLine ();
|
||||
|
||||
foreach (var a in assemblies)
|
||||
implementation.WriteLine ($"MonoImage* __{a.GetName ().Name}_image;");
|
||||
implementation.WriteLine ();
|
||||
|
||||
foreach (var t in types)
|
||||
implementation.WriteLine ($"static MonoClass* {t.Name}_class = nil;");
|
||||
implementation.WriteLine ();
|
||||
|
||||
implementation.WriteLine ("static void __initialize_mono ()");
|
||||
implementation.WriteLine ("{");
|
||||
implementation.WriteLine ("\tif (__mono_context.domain)");
|
||||
implementation.WriteLine ("\t\treturn;");
|
||||
implementation.WriteLine ("\tmono_embeddinator_init (&__mono_context, \"mono_embeddinator_binding\");");
|
||||
implementation.WriteLine ("}");
|
||||
implementation.WriteLine ();
|
||||
|
||||
base.Generate (assemblies);
|
||||
|
||||
headers.WriteLine ();
|
||||
headers.WriteLine ("MONO_EMBEDDINATOR_END_DECLS");
|
||||
}
|
||||
|
||||
protected override void Generate (Assembly a)
|
||||
{
|
||||
var name = a.GetName ().Name;
|
||||
implementation.WriteLine ($"static void __lookup_assembly_{name} ()");
|
||||
implementation.WriteLine ("{");
|
||||
implementation.WriteLine ($"\tif (__{name}_image)");
|
||||
implementation.WriteLine ("\t\treturn;");
|
||||
implementation.WriteLine ($"\t__{name}_image = mono_embeddinator_load_assembly (&__mono_context, \"{name}.dll\");");
|
||||
implementation.WriteLine ("}");
|
||||
implementation.WriteLine ();
|
||||
|
||||
foreach (var t in a.GetTypes ()) {
|
||||
if (!t.IsPublic)
|
||||
continue;
|
||||
Generate (t);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Generate (Type t)
|
||||
{
|
||||
var managed_name = t.Name;
|
||||
implementation.WriteLine ($"static void __lookup_class_{managed_name} ()");
|
||||
implementation.WriteLine ("{");
|
||||
implementation.WriteLine ($"\tif (!{managed_name}_class) {{");
|
||||
implementation.WriteLine ("\t\t__initialize_mono ();");
|
||||
implementation.WriteLine ("\t\t__lookup_assembly_managed ();");
|
||||
implementation.WriteLine ($"\t\t{managed_name}_class = mono_class_from_name (__{t.Assembly.GetName ().Name}_image, \"\", \"{managed_name}\");");
|
||||
implementation.WriteLine ("\t}");
|
||||
implementation.WriteLine ("}");
|
||||
|
||||
var native_name = GetTypeName (t);
|
||||
headers.WriteLine ($"// {t.AssemblyQualifiedName}");
|
||||
headers.WriteLine ($"@interface {native_name} : {GetTypeName (t.BaseType)} {{");
|
||||
headers.WriteLine ("\tMonoEmbedObject* _object;");
|
||||
headers.WriteLine ("}");
|
||||
|
||||
headers.WriteLine ();
|
||||
if (t.IsSealed && t.IsAbstract) {
|
||||
// don't allow instantiation of static types from ObjC code
|
||||
headers.WriteLine ("// a .net static type cannot be initialized");
|
||||
headers.WriteLine ("- (instancetype)init NS_UNAVAILABLE;");
|
||||
headers.WriteLine ();
|
||||
}
|
||||
|
||||
implementation.WriteLine ($"// {t.AssemblyQualifiedName}");
|
||||
implementation.WriteLine ($"@implementation {managed_name}");
|
||||
implementation.WriteLine ();
|
||||
|
||||
foreach (var pi in t.GetProperties ())
|
||||
Generate (pi);
|
||||
|
||||
headers.WriteLine ();
|
||||
headers.WriteLine ("@end");
|
||||
|
||||
implementation.WriteLine ();
|
||||
implementation.WriteLine ("@end");
|
||||
}
|
||||
|
||||
protected override void Generate (PropertyInfo pi)
|
||||
{
|
||||
var getter = pi.GetGetMethod ();
|
||||
var setter = pi.GetSetMethod ();
|
||||
// FIXME: setter only is valid, even if discouraged, in .NET - we should create a SetX method
|
||||
if (getter == null && setter != null)
|
||||
throw new NotSupportedException ();
|
||||
|
||||
// TODO override with attribute ? e.g. [ObjC.Selector ("foo")]
|
||||
var name = CamelCase (pi.Name);
|
||||
|
||||
headers.Write ("@property (nonatomic");
|
||||
if (getter.IsStatic)
|
||||
headers.Write (", class");
|
||||
if (setter == null)
|
||||
headers.Write (", readonly");
|
||||
else
|
||||
headers.Write (", readwrite");
|
||||
var property_type = GetTypeName (pi.PropertyType);
|
||||
headers.WriteLine ($") {property_type} {name};");
|
||||
|
||||
var managed_type_name = pi.DeclaringType.Name;
|
||||
implementation.Write (getter.IsStatic ? '+' : '-');
|
||||
implementation.WriteLine ($" ({property_type}) {name}");
|
||||
implementation.WriteLine ("{");
|
||||
implementation.WriteLine ($"\tconst char __method_name [] = \"{managed_type_name}:{getter.Name}()\";");
|
||||
implementation.WriteLine ("\tstatic MonoMethod* __method = nil;");
|
||||
implementation.WriteLine ("\tif (!__method) {");
|
||||
implementation.WriteLine ($"\t\t__lookup_class_{managed_type_name} ();");
|
||||
implementation.WriteLine ($"\t\t__method = mono_embeddinator_lookup_method (__method_name, {managed_type_name}_class);");
|
||||
implementation.WriteLine ("\t}");
|
||||
implementation.WriteLine ("\tMonoObject* __exception = nil;");
|
||||
implementation.WriteLine ("\tMonoObject* __result = mono_runtime_invoke (__method, nil, nil, &__exception);");
|
||||
implementation.WriteLine ("\tif (__exception)");
|
||||
implementation.WriteLine ("\t\tmono_embeddinator_throw_exception (__exception);");
|
||||
ReturnValue (pi.PropertyType);
|
||||
implementation.WriteLine ("}");
|
||||
if (setter == null)
|
||||
return;
|
||||
|
||||
// TODO override with attribute ? e.g. [ObjC.Selector ("foo")]
|
||||
implementation.Write (getter.IsStatic ? '+' : '-');
|
||||
implementation.WriteLine ($" (void) set{pi.Name}:({property_type})value");
|
||||
implementation.WriteLine ("{");
|
||||
implementation.WriteLine ($"\tconst char __method_name [] = \"{managed_type_name}:{setter.Name}({property_type})\";");
|
||||
implementation.WriteLine ("\tstatic MonoMethod* __method = nil;");
|
||||
implementation.WriteLine ("\tif (!__method) {");
|
||||
implementation.WriteLine ($"\t\t__lookup_class_{managed_type_name} ();");
|
||||
implementation.WriteLine ($"\t\t__method = mono_embeddinator_lookup_method (__method_name, {managed_type_name}_class);");
|
||||
implementation.WriteLine ("\t}");
|
||||
implementation.WriteLine ("\tvoid* __args [1];");
|
||||
implementation.WriteLine ("\t__args [0] = &value;");
|
||||
implementation.WriteLine ("\tMonoObject* __exception = nil;");
|
||||
implementation.WriteLine ("\tMonoObject* __result = mono_runtime_invoke (__method, nil, __args, &__exception);");
|
||||
implementation.WriteLine ("\tif (__exception)");
|
||||
implementation.WriteLine ("\t\tmono_embeddinator_throw_exception (__exception);");
|
||||
implementation.WriteLine ("}");
|
||||
}
|
||||
|
||||
void ReturnValue (Type t)
|
||||
{
|
||||
switch (Type.GetTypeCode (t)) {
|
||||
// unboxing
|
||||
case TypeCode.Boolean:
|
||||
case TypeCode.Int32:
|
||||
var name = GetTypeName (t);
|
||||
implementation.WriteLine ("\tvoid* __unbox = mono_object_unbox (__result);");
|
||||
implementation.WriteLine ($"\treturn *(({name}*)__unbox);");
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFile (string name, string content)
|
||||
{
|
||||
Console.WriteLine ($"\tGenerated: {name}");
|
||||
File.WriteAllText (name, content);
|
||||
}
|
||||
|
||||
public override void Write ()
|
||||
{
|
||||
WriteFile ("bindings.h", headers.ToString ());
|
||||
WriteFile ("bindings.m", implementation.ToString ());
|
||||
}
|
||||
|
||||
// TODO complete mapping (only with corresponding tests)
|
||||
// TODO override with attribute ? e.g. [Obj.Name ("XAMType")]
|
||||
public static string GetTypeName (Type t)
|
||||
{
|
||||
switch (Type.GetTypeCode (t)) {
|
||||
case TypeCode.Object:
|
||||
return t == typeof (object) ? "NSObject" : t.Name;
|
||||
case TypeCode.Boolean:
|
||||
return "bool";
|
||||
case TypeCode.Int32:
|
||||
return "int";
|
||||
default:
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public static string CamelCase (string s)
|
||||
{
|
||||
if (s == null)
|
||||
return null;
|
||||
if (s.Length == 0)
|
||||
return String.Empty;
|
||||
return Char.ToLowerInvariant (s [0]) + s.Substring (1, s.Length - 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{D56A7E3F-FF5C-4EC2-879F-1260ABBD1903}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>managed</RootNamespace>
|
||||
<AssemblyName>managed</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="properties.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
|
||||
// static type
|
||||
public static class Platform {
|
||||
|
||||
// static get-only property
|
||||
public static bool IsWindows {
|
||||
get {
|
||||
switch (Environment.OSVersion.Platform) {
|
||||
case PlatformID.Win32NT:
|
||||
case PlatformID.Win32S:
|
||||
case PlatformID.Win32Windows:
|
||||
case PlatformID.WinCE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static int ExitCode { get; set; }
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include "mono_embeddinator.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
MONO_EMBEDDINATOR_BEGIN_DECLS
|
||||
|
||||
// forward declarations
|
||||
@class Platform;
|
||||
|
||||
// Platform, managed, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
@interface Platform : NSObject {
|
||||
MonoEmbedObject* _object;
|
||||
}
|
||||
|
||||
// a .net static type cannot be initialized
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@property (nonatomic, class, readonly) bool isWindows;
|
||||
@property (nonatomic, class, readwrite) int exitCode;
|
||||
|
||||
@end
|
||||
|
||||
MONO_EMBEDDINATOR_END_DECLS
|
|
@ -0,0 +1,86 @@
|
|||
#include "bindings.h"
|
||||
#include "glib.h"
|
||||
#include <mono/jit/jit.h>
|
||||
#include <mono/metadata/assembly.h>
|
||||
#include <mono/metadata/object.h>
|
||||
#include <mono/metadata/mono-config.h>
|
||||
#include <mono/metadata/debug-helpers.h>
|
||||
|
||||
mono_embeddinator_context_t __mono_context;
|
||||
|
||||
MonoImage* __managed_image;
|
||||
|
||||
static MonoClass* Platform_class = nil;
|
||||
|
||||
static void __initialize_mono ()
|
||||
{
|
||||
if (__mono_context.domain)
|
||||
return;
|
||||
mono_embeddinator_init (&__mono_context, "mono_embeddinator_binding");
|
||||
}
|
||||
|
||||
static void __lookup_assembly_managed ()
|
||||
{
|
||||
if (__managed_image)
|
||||
return;
|
||||
__managed_image = mono_embeddinator_load_assembly (&__mono_context, "managed.dll");
|
||||
}
|
||||
|
||||
static void __lookup_class_Platform ()
|
||||
{
|
||||
if (!Platform_class) {
|
||||
__initialize_mono ();
|
||||
__lookup_assembly_managed ();
|
||||
Platform_class = mono_class_from_name (__managed_image, "", "Platform");
|
||||
}
|
||||
}
|
||||
// Platform, managed, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
@implementation Platform
|
||||
|
||||
+ (bool) isWindows
|
||||
{
|
||||
const char __method_name [] = "Platform:get_IsWindows()";
|
||||
static MonoMethod* __method = nil;
|
||||
if (!__method) {
|
||||
__lookup_class_Platform ();
|
||||
__method = mono_embeddinator_lookup_method (__method_name, Platform_class);
|
||||
}
|
||||
MonoObject* __exception = nil;
|
||||
MonoObject* __result = mono_runtime_invoke (__method, nil, nil, &__exception);
|
||||
if (__exception)
|
||||
mono_embeddinator_throw_exception (__exception);
|
||||
void* __unbox = mono_object_unbox (__result);
|
||||
return *((bool*)__unbox);
|
||||
}
|
||||
+ (int) exitCode
|
||||
{
|
||||
const char __method_name [] = "Platform:get_ExitCode()";
|
||||
static MonoMethod* __method = nil;
|
||||
if (!__method) {
|
||||
__lookup_class_Platform ();
|
||||
__method = mono_embeddinator_lookup_method (__method_name, Platform_class);
|
||||
}
|
||||
MonoObject* __exception = nil;
|
||||
MonoObject* __result = mono_runtime_invoke (__method, nil, nil, &__exception);
|
||||
if (__exception)
|
||||
mono_embeddinator_throw_exception (__exception);
|
||||
void* __unbox = mono_object_unbox (__result);
|
||||
return *((int*)__unbox);
|
||||
}
|
||||
+ (void) setExitCode:(int)value
|
||||
{
|
||||
const char __method_name [] = "Platform:set_ExitCode(int)";
|
||||
static MonoMethod* __method = nil;
|
||||
if (!__method) {
|
||||
__lookup_class_Platform ();
|
||||
__method = mono_embeddinator_lookup_method (__method_name, Platform_class);
|
||||
}
|
||||
void* __args [1];
|
||||
__args [0] = &value;
|
||||
MonoObject* __exception = nil;
|
||||
MonoObject* __result = mono_runtime_invoke (__method, nil, __args, &__exception);
|
||||
if (__exception)
|
||||
mono_embeddinator_throw_exception (__exception);
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
* String functions
|
||||
*
|
||||
* Author:
|
||||
* Miguel de Icaza (miguel@novell.com)
|
||||
* Aaron Bockover (abockover@novell.com)
|
||||
*
|
||||
* (C) 2006 Novell, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "glib.h"
|
||||
|
||||
void g_free (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
gpointer g_realloc (gpointer obj, gsize size)
|
||||
{
|
||||
return realloc(obj, size);
|
||||
}
|
||||
|
||||
gpointer g_malloc (gsize x)
|
||||
{
|
||||
return malloc(x);
|
||||
}
|
||||
|
||||
gpointer g_malloc0 (gsize x)
|
||||
{
|
||||
return calloc(1, x);
|
||||
}
|
||||
|
||||
gpointer
|
||||
g_memdup (gconstpointer mem, guint byte_size)
|
||||
{
|
||||
gpointer ptr;
|
||||
|
||||
if (mem == NULL)
|
||||
return NULL;
|
||||
|
||||
ptr = g_malloc (byte_size);
|
||||
if (ptr != NULL)
|
||||
memcpy (ptr, mem, byte_size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
gchar *
|
||||
g_strdup (const gchar *str)
|
||||
{
|
||||
if (str) { return (gchar*) g_memdup (str, (guint)strlen (str) + 1); }
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define INITIAL_CAPACITY 16
|
||||
|
||||
#define element_offset(p,i) ((p)->array.data + (i) * (p)->element_size)
|
||||
#define element_length(p,i) ((i) * (p)->element_size)
|
||||
|
||||
typedef struct {
|
||||
GArray array;
|
||||
gboolean clear_;
|
||||
guint element_size;
|
||||
gboolean zero_terminated;
|
||||
guint capacity;
|
||||
} GArrayPriv;
|
||||
|
||||
static void
|
||||
ensure_capacity (GArrayPriv *priv, guint capacity)
|
||||
{
|
||||
guint new_capacity;
|
||||
|
||||
if (capacity <= priv->capacity)
|
||||
return;
|
||||
|
||||
new_capacity = (capacity + 63) & ~63;
|
||||
|
||||
priv->array.data = g_realloc (priv->array.data, element_length (priv, new_capacity));
|
||||
|
||||
if (priv->clear_) {
|
||||
memset (element_offset (priv, priv->capacity),
|
||||
0,
|
||||
element_length (priv, new_capacity - priv->capacity));
|
||||
}
|
||||
|
||||
priv->capacity = new_capacity;
|
||||
}
|
||||
|
||||
GArray *
|
||||
g_array_new (gboolean zero_terminated,
|
||||
gboolean clear_,
|
||||
guint element_size)
|
||||
{
|
||||
GArrayPriv *rv = g_new0 (GArrayPriv, 1);
|
||||
rv->zero_terminated = zero_terminated;
|
||||
rv->clear_ = clear_;
|
||||
rv->element_size = element_size;
|
||||
|
||||
ensure_capacity (rv, INITIAL_CAPACITY);
|
||||
|
||||
return (GArray*)rv;
|
||||
}
|
||||
|
||||
GArray *
|
||||
g_array_sized_new (gboolean zero_terminated,
|
||||
gboolean clear_,
|
||||
guint element_size,
|
||||
guint reserved_size)
|
||||
{
|
||||
GArrayPriv *rv = g_new0 (GArrayPriv, 1);
|
||||
rv->zero_terminated = zero_terminated;
|
||||
rv->clear_ = clear_;
|
||||
rv->element_size = element_size;
|
||||
|
||||
ensure_capacity (rv, reserved_size);
|
||||
|
||||
return (GArray*)rv;
|
||||
}
|
||||
|
||||
gchar*
|
||||
g_array_free (GArray *array,
|
||||
gboolean free_segment)
|
||||
{
|
||||
gchar* rv = NULL;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
if (free_segment)
|
||||
g_free (array->data);
|
||||
else
|
||||
rv = array->data;
|
||||
|
||||
g_free (array);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
GArray *
|
||||
g_array_append_vals (GArray *array,
|
||||
gconstpointer data,
|
||||
guint len)
|
||||
{
|
||||
GArrayPriv *priv = (GArrayPriv*)array;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
ensure_capacity (priv, priv->array.len + len + (priv->zero_terminated ? 1 : 0));
|
||||
|
||||
memmove (element_offset (priv, priv->array.len),
|
||||
data,
|
||||
element_length (priv, len));
|
||||
|
||||
priv->array.len += len;
|
||||
|
||||
if (priv->zero_terminated) {
|
||||
memset (element_offset (priv, priv->array.len),
|
||||
0,
|
||||
priv->element_size);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GArray*
|
||||
g_array_insert_vals (GArray *array,
|
||||
guint index_,
|
||||
gconstpointer data,
|
||||
guint len)
|
||||
{
|
||||
GArrayPriv *priv = (GArrayPriv*)array;
|
||||
guint extra = (priv->zero_terminated ? 1 : 0);
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
ensure_capacity (priv, array->len + len + extra);
|
||||
|
||||
/* first move the existing elements out of the way */
|
||||
memmove (element_offset (priv, index_ + len),
|
||||
element_offset (priv, index_),
|
||||
element_length (priv, array->len - index_));
|
||||
|
||||
/* then copy the new elements into the array */
|
||||
memmove (element_offset (priv, index_),
|
||||
data,
|
||||
element_length (priv, len));
|
||||
|
||||
array->len += len;
|
||||
|
||||
if (priv->zero_terminated) {
|
||||
memset (element_offset (priv, priv->array.len),
|
||||
0,
|
||||
priv->element_size);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GArray*
|
||||
g_array_remove_index (GArray *array,
|
||||
guint index_)
|
||||
{
|
||||
GArrayPriv *priv = (GArrayPriv*)array;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
memmove (element_offset (priv, index_),
|
||||
element_offset (priv, index_ + 1),
|
||||
element_length (priv, array->len - index_));
|
||||
|
||||
array->len --;
|
||||
|
||||
if (priv->zero_terminated) {
|
||||
memset (element_offset (priv, priv->array.len),
|
||||
0,
|
||||
priv->element_size);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GArray*
|
||||
g_array_remove_index_fast (GArray *array,
|
||||
guint index_)
|
||||
{
|
||||
GArrayPriv *priv = (GArrayPriv*)array;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
memmove (element_offset (priv, index_),
|
||||
element_offset (priv, array->len - 1),
|
||||
element_length (priv, 1));
|
||||
|
||||
array->len --;
|
||||
|
||||
if (priv->zero_terminated) {
|
||||
memset (element_offset (priv, priv->array.len),
|
||||
0,
|
||||
priv->element_size);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
void
|
||||
g_array_set_size (GArray *array, gint length)
|
||||
{
|
||||
GArrayPriv *priv = (GArrayPriv*)array;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (length >= 0);
|
||||
|
||||
if (length == priv->capacity)
|
||||
return; // nothing to be done
|
||||
|
||||
if (length > priv->capacity) {
|
||||
// grow the array
|
||||
ensure_capacity (priv, length);
|
||||
}
|
||||
|
||||
array->len = length;
|
||||
}
|
||||
|
||||
#define GROW_IF_NECESSARY(s,l) { \
|
||||
if(s->len + l >= s->allocated_len) { \
|
||||
s->allocated_len = (s->allocated_len + l + 16) * 2; \
|
||||
s->str = g_realloc(s->str, s->allocated_len); \
|
||||
} \
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_new_len (const gchar *init, gssize len)
|
||||
{
|
||||
GString *ret = g_new (GString, 1);
|
||||
|
||||
if (init == NULL)
|
||||
ret->len = 0;
|
||||
else
|
||||
ret->len = len < 0 ? strlen(init) : len;
|
||||
ret->allocated_len = MAX(ret->len + 1, 16);
|
||||
ret->str = g_malloc(ret->allocated_len);
|
||||
if (init)
|
||||
memcpy(ret->str, init, ret->len);
|
||||
ret->str[ret->len] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_new (const gchar *init)
|
||||
{
|
||||
return g_string_new_len(init, -1);
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_sized_new (gsize default_size)
|
||||
{
|
||||
GString *ret = g_new (GString, 1);
|
||||
|
||||
ret->str = g_malloc (default_size);
|
||||
ret->str [0] = 0;
|
||||
ret->len = 0;
|
||||
ret->allocated_len = default_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
g_string_free (GString *string, gboolean free_segment)
|
||||
{
|
||||
gchar *data;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
|
||||
data = string->str;
|
||||
g_free(string);
|
||||
|
||||
if(!free_segment) {
|
||||
return data;
|
||||
}
|
||||
|
||||
g_free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_append_len (GString *string, const gchar *val, gssize len)
|
||||
{
|
||||
g_return_val_if_fail(string != NULL, NULL);
|
||||
g_return_val_if_fail(val != NULL, string);
|
||||
|
||||
if(len < 0) {
|
||||
len = strlen(val);
|
||||
}
|
||||
|
||||
GROW_IF_NECESSARY(string, len);
|
||||
memcpy(string->str + string->len, val, len);
|
||||
string->len += len;
|
||||
string->str[string->len] = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_append (GString *string, const gchar *val)
|
||||
{
|
||||
g_return_val_if_fail(string != NULL, NULL);
|
||||
g_return_val_if_fail(val != NULL, string);
|
||||
|
||||
return g_string_append_len(string, val, -1);
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_append_c (GString *string, gchar c)
|
||||
{
|
||||
g_return_val_if_fail(string != NULL, NULL);
|
||||
|
||||
GROW_IF_NECESSARY(string, 1);
|
||||
|
||||
string->str[string->len] = c;
|
||||
string->str[string->len + 1] = 0;
|
||||
string->len++;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_prepend (GString *string, const gchar *val)
|
||||
{
|
||||
gssize len;
|
||||
|
||||
g_return_val_if_fail (string != NULL, string);
|
||||
g_return_val_if_fail (val != NULL, string);
|
||||
|
||||
len = strlen (val);
|
||||
|
||||
GROW_IF_NECESSARY(string, len);
|
||||
memmove(string->str + len, string->str, string->len + 1);
|
||||
memcpy(string->str, val, len);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_insert (GString *string, gssize pos, const gchar *val)
|
||||
{
|
||||
gssize len;
|
||||
|
||||
g_return_val_if_fail (string != NULL, string);
|
||||
g_return_val_if_fail (val != NULL, string);
|
||||
g_return_val_if_fail (pos <= string->len, string);
|
||||
|
||||
len = strlen (val);
|
||||
|
||||
GROW_IF_NECESSARY(string, len);
|
||||
memmove(string->str + pos + len, string->str + pos, string->len - pos - len + 1);
|
||||
memcpy(string->str + pos, val, len);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_truncate (GString *string, gsize len)
|
||||
{
|
||||
g_return_val_if_fail (string != NULL, string);
|
||||
|
||||
/* Silent return */
|
||||
if (len >= string->len)
|
||||
return string;
|
||||
|
||||
string->len = len;
|
||||
string->str[len] = 0;
|
||||
return string;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_set_size (GString *string, gsize len)
|
||||
{
|
||||
g_return_val_if_fail (string != NULL, string);
|
||||
|
||||
GROW_IF_NECESSARY(string, len);
|
||||
|
||||
string->len = len;
|
||||
string->str[len] = 0;
|
||||
return string;
|
||||
}
|
||||
|
||||
GString *
|
||||
g_string_erase (GString *string, gssize pos, gssize len)
|
||||
{
|
||||
g_return_val_if_fail (string != NULL, string);
|
||||
|
||||
/* Silent return */
|
||||
if (pos >= string->len)
|
||||
return string;
|
||||
|
||||
if (len == -1 || (pos + len) >= string->len) {
|
||||
string->str[pos] = 0;
|
||||
}
|
||||
else {
|
||||
memmove (string->str + pos, string->str + pos + len, string->len - (pos + len) + 1);
|
||||
string->len -= len;
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
#ifndef __GLIB_H
|
||||
#define __GLIB_H
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef G_HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/* For alloca */
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
# define offsetof(s_name,n_name) (size_t)(char *)&(((s_name*)0)->m_name)
|
||||
#endif
|
||||
|
||||
#define __EGLIB_X11 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define G_BEGIN_DECLS extern "C" {
|
||||
#define G_END_DECLS }
|
||||
#else
|
||||
#define G_BEGIN_DECLS
|
||||
#define G_END_DECLS
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Basic data types
|
||||
*/
|
||||
typedef int gint;
|
||||
typedef unsigned int guint;
|
||||
typedef short gshort;
|
||||
typedef unsigned short gushort;
|
||||
typedef long glong;
|
||||
typedef unsigned long gulong;
|
||||
typedef void * gpointer;
|
||||
typedef const void * gconstpointer;
|
||||
typedef char gchar;
|
||||
typedef unsigned char guchar;
|
||||
|
||||
/* Types defined in terms of the stdint.h */
|
||||
typedef int8_t gint8;
|
||||
typedef uint8_t guint8;
|
||||
typedef int16_t gint16;
|
||||
typedef uint16_t guint16;
|
||||
typedef int32_t gint32;
|
||||
typedef uint32_t guint32;
|
||||
typedef int64_t gint64;
|
||||
typedef uint64_t guint64;
|
||||
typedef float gfloat;
|
||||
typedef double gdouble;
|
||||
typedef int32_t gboolean;
|
||||
|
||||
typedef guint16 gunichar2;
|
||||
typedef guint32 gunichar;
|
||||
|
||||
typedef unsigned long gsize;
|
||||
typedef signed long gssize;
|
||||
|
||||
/*
|
||||
* Macros
|
||||
*/
|
||||
#define G_N_ELEMENTS(s) (sizeof(s) / sizeof ((s) [0]))
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define G_MINSHORT SHRT_MIN
|
||||
#define G_MAXSHORT SHRT_MAX
|
||||
#define G_MAXUSHORT USHRT_MAX
|
||||
#define G_MAXINT INT_MAX
|
||||
#define G_MININT INT_MIN
|
||||
#define G_MAXINT32 INT32_MAX
|
||||
#define G_MAXUINT32 UINT32_MAX
|
||||
#define G_MININT32 INT32_MIN
|
||||
#define G_MININT64 INT64_MIN
|
||||
#define G_MAXINT64 INT64_MAX
|
||||
#define G_MAXUINT64 UINT64_MAX
|
||||
|
||||
#define G_LITTLE_ENDIAN 1234
|
||||
#define G_BIG_ENDIAN 4321
|
||||
#define G_STMT_START do
|
||||
#define G_STMT_END while (0)
|
||||
|
||||
#define G_USEC_PER_SEC 1000000
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(a) ((a) > 0 ? (a) : -(a))
|
||||
#endif
|
||||
|
||||
#define G_STRUCT_OFFSET(p_type,field) offsetof(p_type,field)
|
||||
|
||||
#define EGLIB_STRINGIFY(x) #x
|
||||
#define EGLIB_TOSTRING(x) EGLIB_STRINGIFY(x)
|
||||
#define G_STRLOC __FILE__ ":" EGLIB_TOSTRING(__LINE__) ":"
|
||||
|
||||
#define G_CONST_RETURN const
|
||||
|
||||
#define G_GUINT64_FORMAT PRIu64
|
||||
#define G_GINT64_FORMAT PRIi64
|
||||
#define G_GUINT32_FORMAT PRIu32
|
||||
#define G_GINT32_FORMAT PRIi32
|
||||
|
||||
/*
|
||||
* Allocation
|
||||
*/
|
||||
void g_free (void *ptr);
|
||||
gpointer g_realloc (gpointer obj, gsize size);
|
||||
gpointer g_malloc (gsize x);
|
||||
gpointer g_malloc0 (gsize x);
|
||||
gpointer g_calloc (gsize n, gsize x);
|
||||
gpointer g_try_malloc (gsize x);
|
||||
gpointer g_try_realloc (gpointer obj, gsize size);
|
||||
|
||||
#define g_new(type,size) ((type *) g_malloc (sizeof (type) * (size)))
|
||||
#define g_new0(type,size) ((type *) g_malloc0 (sizeof (type)* (size)))
|
||||
#define g_newa(type,size) ((type *) alloca (sizeof (type) * (size)))
|
||||
|
||||
#define g_memmove(dest,src,len) memmove (dest, src, len)
|
||||
#define g_renew(struct_type, mem, n_structs) g_realloc (mem, sizeof (struct_type) * n_structs)
|
||||
#define g_alloca(size) alloca (size)
|
||||
|
||||
gpointer g_memdup (gconstpointer mem, guint byte_size);
|
||||
gchar *g_strdup (const gchar *str);
|
||||
gchar **g_strdupv (gchar **str_array);
|
||||
|
||||
/*
|
||||
* Precondition macros
|
||||
*/
|
||||
#define g_warn_if_fail(x) G_STMT_START { if (!(x)) { g_warning ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); } } G_STMT_END
|
||||
#define g_return_if_fail(x) G_STMT_START { if (!(x)) { g_critical ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return; } } G_STMT_END
|
||||
#define g_return_val_if_fail(x,e) G_STMT_START { if (!(x)) { g_critical ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return (e); } } G_STMT_END
|
||||
|
||||
/*
|
||||
* Array
|
||||
*/
|
||||
|
||||
typedef struct _GArray GArray;
|
||||
struct _GArray {
|
||||
gchar *data;
|
||||
gint len;
|
||||
};
|
||||
|
||||
GArray *g_array_new (gboolean zero_terminated, gboolean clear_, guint element_size);
|
||||
GArray *g_array_sized_new (gboolean zero_terminated, gboolean clear_, guint element_size, guint reserved_size);
|
||||
gchar* g_array_free (GArray *array, gboolean free_segment);
|
||||
GArray *g_array_append_vals (GArray *array, gconstpointer data, guint len);
|
||||
GArray* g_array_insert_vals (GArray *array, guint index_, gconstpointer data, guint len);
|
||||
GArray* g_array_remove_index (GArray *array, guint index_);
|
||||
GArray* g_array_remove_index_fast (GArray *array, guint index_);
|
||||
void g_array_set_size (GArray *array, gint length);
|
||||
|
||||
#define g_array_append_val(a,v) (g_array_append_vals((a),&(v),1))
|
||||
#define g_array_insert_val(a,i,v) (g_array_insert_vals((a),(i),&(v),1))
|
||||
#define g_array_index(a,t,i) *(t*)(((a)->data) + sizeof(t) * (i))
|
||||
|
||||
/*
|
||||
* String type
|
||||
*/
|
||||
typedef struct _GString {
|
||||
char *str;
|
||||
gsize len;
|
||||
gsize allocated_len;
|
||||
} GString;
|
||||
|
||||
GString *g_string_new (const gchar *init);
|
||||
GString *g_string_new_len (const gchar *init, gssize len);
|
||||
GString *g_string_sized_new (gsize default_size);
|
||||
gchar *g_string_free (GString *string, gboolean free_segment);
|
||||
GString *g_string_append (GString *string, const gchar *val);
|
||||
GString *g_string_append_c (GString *string, gchar c);
|
||||
GString *g_string_append (GString *string, const gchar *val);
|
||||
GString *g_string_append_len (GString *string, const gchar *val, gssize len);
|
||||
GString *g_string_truncate (GString *string, gsize len);
|
||||
GString *g_string_prepend (GString *string, const gchar *val);
|
||||
GString *g_string_insert (GString *string, gssize pos, const gchar *val);
|
||||
GString *g_string_set_size (GString *string, gsize len);
|
||||
GString *g_string_erase (GString *string, gssize pos, gssize len);
|
||||
|
||||
#define g_string_sprintfa g_string_append_printf
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(a,low,high) (((a) < (low)) ? (low) : (((a) > (high)) ? (high) : (a)))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define eg_unreachable() __assume(0)
|
||||
#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 5)))
|
||||
#define eg_unreachable() __builtin_unreachable()
|
||||
#else
|
||||
#define eg_unreachable()
|
||||
#endif
|
||||
|
||||
#define g_assert(x) G_STMT_START { if (G_UNLIKELY (!(x))) g_assertion_message ("* Assertion at %s:%d, condition `%s' not met\n", __FILE__, __LINE__, #x); } G_STMT_END
|
||||
#define g_assert_not_reached() G_STMT_START { g_assertion_message ("* Assertion: should not be reached at %s:%d\n", __FILE__, __LINE__); eg_unreachable(); } G_STMT_END
|
||||
|
||||
#define g_critical(format, ...)
|
||||
|
||||
/*
|
||||
* Path
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define G_DIR_SEPARATOR '\\'
|
||||
#define G_DIR_SEPARATOR_S "\\"
|
||||
#else
|
||||
#define G_DIR_SEPARATOR '/'
|
||||
#define G_DIR_SEPARATOR_S "/"
|
||||
#endif
|
||||
|
||||
gchar *g_build_path (const gchar *separator, const gchar *first_element, ...);
|
||||
#define g_build_filename(x, ...) g_build_path(G_DIR_SEPARATOR_S, x, __VA_ARGS__)
|
||||
gchar *g_path_get_dirname (const gchar *filename);
|
||||
gchar *g_path_get_basename (const char *filename);
|
||||
gchar *g_find_program_in_path (const gchar *program);
|
||||
gchar *g_get_current_dir (void);
|
||||
gboolean g_path_is_absolute (const char *filename);
|
||||
|
||||
#define _EGLIB_MAJOR 2
|
||||
#define _EGLIB_MIDDLE 4
|
||||
#define _EGLIB_MINOR 0
|
||||
|
||||
#define GLIB_CHECK_VERSION(a,b,c) ((a < _EGLIB_MAJOR) || (a == _EGLIB_MAJOR && (b < _EGLIB_MIDDLE || (b == _EGLIB_MIDDLE && c <= _EGLIB_MINOR))))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
|
Двоичный файл не отображается.
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* Mono managed-to-native support code.
|
||||
*
|
||||
* Author:
|
||||
* Joao Matos (joao.matos@xamarin.com)
|
||||
*
|
||||
* (C) 2016 Microsoft, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mono_embeddinator.h"
|
||||
#include "glib.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <errno.h>
|
||||
#include <libproc.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OBJC__)
|
||||
#include <objc/runtime.h>
|
||||
#include <objc/objc-runtime.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <mono/jit/jit.h>
|
||||
#include <mono/metadata/mono-config.h>
|
||||
#include <mono/metadata/assembly.h>
|
||||
#include <mono/metadata/debug-helpers.h>
|
||||
|
||||
mono_embeddinator_context_t* _current_context;
|
||||
|
||||
mono_embeddinator_context_t* mono_embeddinator_get_context()
|
||||
{
|
||||
return _current_context;
|
||||
}
|
||||
|
||||
void mono_embeddinator_set_context(mono_embeddinator_context_t* ctx)
|
||||
{
|
||||
_current_context = ctx;
|
||||
}
|
||||
|
||||
#if defined(__OBJC__)
|
||||
id allocAndInitAutoreleasePool()
|
||||
{
|
||||
Class NSAutoreleasePoolClass = objc_getClass("NSAutoreleasePool");
|
||||
id pool = class_createInstance(NSAutoreleasePoolClass, 0);
|
||||
return objc_msgSend(pool, sel_registerName("init"));
|
||||
}
|
||||
|
||||
void drainAutoreleasePool(id pool)
|
||||
{
|
||||
(void)objc_msgSend(pool, sel_registerName("drain"));
|
||||
}
|
||||
|
||||
#define AUTORELEASE_POOL_DEFAULT_VALUE ((id)-1)
|
||||
static id _autoreleasePool = AUTORELEASE_POOL_DEFAULT_VALUE;
|
||||
#endif
|
||||
|
||||
int mono_embeddinator_init(mono_embeddinator_context_t* ctx, const char* domain)
|
||||
{
|
||||
if (ctx == 0 || ctx->domain != 0)
|
||||
return false;
|
||||
|
||||
mono_config_parse(NULL);
|
||||
ctx->domain = mono_jit_init_version(domain, "v4.0.30319");
|
||||
|
||||
mono_embeddinator_set_context(ctx);
|
||||
|
||||
#if defined(__OBJC__)
|
||||
if (_autoreleasePool == AUTORELEASE_POOL_DEFAULT_VALUE)
|
||||
_autoreleasePool = allocAndInitAutoreleasePool();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int mono_embeddinator_destroy(mono_embeddinator_context_t* ctx)
|
||||
{
|
||||
if (ctx == 0 || ctx->domain != 0)
|
||||
return false;
|
||||
|
||||
mono_jit_cleanup (ctx->domain);
|
||||
|
||||
#if defined(__OBJC__)
|
||||
if (_autoreleasePool != AUTORELEASE_POOL_DEFAULT_VALUE)
|
||||
{
|
||||
drainAutoreleasePool(_autoreleasePool);
|
||||
_autoreleasePool = AUTORELEASE_POOL_DEFAULT_VALUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static GString* get_current_executable_path()
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
int ret;
|
||||
pid_t pid;
|
||||
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
|
||||
|
||||
pid = getpid();
|
||||
ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
|
||||
|
||||
return (ret > 0) ? g_string_new(pathbuf) : 0;
|
||||
#elif defined(_WIN32)
|
||||
HMODULE hModule = GetModuleHandleW(0);
|
||||
CHAR pathbuf[MAX_PATH];
|
||||
DWORD ret = GetModuleFileNameA(hModule, pathbuf, MAX_PATH);
|
||||
|
||||
return (ret > 0) ? g_string_new(pathbuf) : 0;
|
||||
#else
|
||||
g_assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
static gchar*
|
||||
strrchr_seperator (const gchar* filename)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
char *p2;
|
||||
#endif
|
||||
char *p;
|
||||
|
||||
p = strrchr (filename, G_DIR_SEPARATOR);
|
||||
#ifdef G_OS_WIN32
|
||||
p2 = strrchr (filename, '/');
|
||||
if (p2 > p)
|
||||
p = p2;
|
||||
#endif
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char* mono_embeddinator_search_assembly(const char* assembly)
|
||||
{
|
||||
GString* path = get_current_executable_path();
|
||||
|
||||
gchar* sep = strrchr_seperator(path->str);
|
||||
g_string_truncate(path, sep - path->str);
|
||||
|
||||
g_string_append(path, G_DIR_SEPARATOR_S);
|
||||
g_string_append(path, assembly);
|
||||
|
||||
char* data = path->str;
|
||||
g_string_free(path, /*free_segment=*/ FALSE);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
MonoImage* mono_embeddinator_load_assembly(mono_embeddinator_context_t* ctx, const char* assembly)
|
||||
{
|
||||
const char* path = mono_embeddinator_search_assembly(assembly);
|
||||
MonoAssembly* mono_assembly = mono_domain_assembly_open(ctx->domain, path);
|
||||
if (mono_assembly == 0)
|
||||
{
|
||||
mono_embeddinator_error_t __error;
|
||||
__error.type = MONO_EMBEDDINATOR_ASSEMBLY_OPEN_FAILED;
|
||||
__error.string = path;
|
||||
mono_embeddinator_error(__error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mono_assembly_get_image(mono_assembly);
|
||||
}
|
||||
|
||||
static mono_embeddinator_assembly_search_hook_t g_assembly_search_hook = 0;
|
||||
|
||||
void* mono_embeddinator_install_assembly_search_hook(mono_embeddinator_assembly_search_hook_t hook)
|
||||
{
|
||||
mono_embeddinator_assembly_search_hook_t prev = g_assembly_search_hook;
|
||||
g_assembly_search_hook = hook;
|
||||
return (void*)prev;
|
||||
}
|
||||
|
||||
MonoClass* mono_embeddinator_search_class(const char* assembly, const char* _namespace,
|
||||
const char* name)
|
||||
{
|
||||
mono_embeddinator_context_t* ctx = mono_embeddinator_get_context();
|
||||
|
||||
const char* path = mono_embeddinator_search_assembly(assembly);
|
||||
MonoAssembly* mono_assembly = mono_domain_assembly_open(ctx->domain, path);
|
||||
|
||||
if (mono_assembly == 0)
|
||||
{
|
||||
mono_embeddinator_error_t error;
|
||||
error.type = MONO_EMBEDDINATOR_ASSEMBLY_OPEN_FAILED;
|
||||
error.string = path;
|
||||
mono_embeddinator_error(error);
|
||||
}
|
||||
|
||||
MonoImage* image = mono_assembly_get_image(mono_assembly);
|
||||
MonoClass* klass = mono_class_from_name(image, _namespace, name);
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
MonoMethod* mono_embeddinator_lookup_method(const char* method_name, MonoClass *klass)
|
||||
{
|
||||
MonoMethodDesc* desc = mono_method_desc_new(method_name, /*include_namespace=*/true);
|
||||
MonoMethod* method = mono_method_desc_search_in_class(desc, klass);
|
||||
mono_method_desc_free(desc);
|
||||
|
||||
if (!method)
|
||||
{
|
||||
mono_embeddinator_error_t error;
|
||||
error.type = MONO_EMBEDDINATOR_METHOD_LOOKUP_FAILED;
|
||||
error.string = method_name;
|
||||
mono_embeddinator_error(error);
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
void mono_embeddinator_throw_exception(MonoObject *exception)
|
||||
{
|
||||
mono_embeddinator_error_t error;
|
||||
error.type = MONO_EMBEDDINATOR_EXCEPTION_THROWN;
|
||||
error.exception = (MonoException*) exception;
|
||||
mono_embeddinator_error(error);
|
||||
}
|
||||
|
||||
static mono_embeddinator_error_report_hook_t g_error_report_hook = 0;
|
||||
|
||||
void* mono_embeddinator_install_error_report_hook(mono_embeddinator_error_report_hook_t hook)
|
||||
{
|
||||
mono_embeddinator_error_report_hook_t prev = g_error_report_hook;
|
||||
g_error_report_hook = hook;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void mono_embeddinator_error(mono_embeddinator_error_t error)
|
||||
{
|
||||
if (g_error_report_hook == 0)
|
||||
return;
|
||||
|
||||
g_error_report_hook(error);
|
||||
}
|
||||
|
||||
void* mono_embeddinator_create_object(MonoObject* instance)
|
||||
{
|
||||
MonoEmbedObject* object = g_new(MonoEmbedObject, 1);
|
||||
mono_embeddinator_init_object(object, instance);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void mono_embeddinator_init_object(MonoEmbedObject* object, MonoObject* instance)
|
||||
{
|
||||
object->_class = mono_object_get_class(instance);
|
||||
object->_handle = mono_gchandle_new(instance, /*pinned=*/false);
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Mono managed-to-native support code.
|
||||
*
|
||||
* Author:
|
||||
* Joao Matos (joao.matos@xamarin.com)
|
||||
*
|
||||
* (C) 2016 Microsoft, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdbool>
|
||||
#include <cstdint>
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define MONO_EMBEDDINATOR_BEGIN_DECLS extern "C" {
|
||||
#define MONO_EMBEDDINATOR_END_DECLS }
|
||||
#else
|
||||
#define MONO_EMBEDDINATOR_BEGIN_DECLS
|
||||
#define MONO_EMBEDDINATOR_END_DECLS
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define MONO_EMBEDDINATOR_API_EXPORT __declspec(dllexport)
|
||||
#define MONO_EMBEDDINATOR_API_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
#define MONO_EMBEDDINATOR_API_EXPORT __attribute__ ((visibility ("default")))
|
||||
#define MONO_EMBEDDINATOR_API_IMPORT
|
||||
#endif
|
||||
|
||||
#if defined(MONO_EMBEDDINATOR_DLL_EXPORT)
|
||||
#define MONO_EMBEDDINATOR_API MONO_EMBEDDINATOR_API_EXPORT
|
||||
#else
|
||||
#define MONO_EMBEDDINATOR_API MONO_EMBEDDINATOR_API_IMPORT
|
||||
#endif
|
||||
|
||||
typedef uint16_t gunichar2;
|
||||
|
||||
typedef struct _GArray GArray;
|
||||
typedef struct _GString GString;
|
||||
|
||||
typedef struct _MonoDomain MonoDomain;
|
||||
typedef struct _MonoException MonoException;
|
||||
typedef struct _MonoClass MonoClass;
|
||||
typedef struct _MonoObject MonoObject;
|
||||
typedef struct _MonoImage MonoImage;
|
||||
typedef struct _MonoMethod MonoMethod;
|
||||
|
||||
MONO_EMBEDDINATOR_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* Represents a managed-to-native binding context.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MonoDomain* domain;
|
||||
} mono_embeddinator_context_t;
|
||||
|
||||
/**
|
||||
* Initializes a managed-to-native binding context.
|
||||
* Returns a boolean indicating success or failure.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
int mono_embeddinator_init(mono_embeddinator_context_t* ctx, const char* domain);
|
||||
|
||||
/**
|
||||
* Destroys the managed-to-native binding context.
|
||||
* Returns a boolean indicating success or failure.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
int mono_embeddinator_destroy(mono_embeddinator_context_t* ctx);
|
||||
|
||||
/**
|
||||
* Returns the current context.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
mono_embeddinator_context_t* mono_embeddinator_get_context();
|
||||
|
||||
/**
|
||||
* Sets the current context.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void mono_embeddinator_set_context(mono_embeddinator_context_t* ctx);
|
||||
|
||||
/**
|
||||
* Loads an assembly into the context.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
MonoImage* mono_embeddinator_load_assembly(mono_embeddinator_context_t* ctx,
|
||||
const char* assembly);
|
||||
|
||||
/**
|
||||
* Searches and returns the path to the given managed assembly.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
char* mono_embeddinator_search_assembly(const char* assembly);
|
||||
|
||||
/** Represents the assembly search hook function type. */
|
||||
typedef const char* (*mono_embeddinator_assembly_search_hook_t)(const char*);
|
||||
|
||||
/**
|
||||
* Installs an hook that returns the path to the given managed assembly.
|
||||
* Returns the previous installed hook.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void* mono_embeddinator_install_assembly_search_hook(mono_embeddinator_assembly_search_hook_t hook);
|
||||
|
||||
/**
|
||||
* Searches and returns for the Mono class in the given assembly.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
MonoClass* mono_embeddinator_search_class(const char* assembly, const char* _namespace,
|
||||
const char* name);
|
||||
|
||||
/**
|
||||
* Looks up and returns a MonoMethod* for a given Mono class and method name.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
MonoMethod* mono_embeddinator_lookup_method(const char* method_name, MonoClass* klass);
|
||||
|
||||
/**
|
||||
* Throws an exception based on a given Mono exception object.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void mono_embeddinator_throw_exception(MonoObject* exception);
|
||||
|
||||
/**
|
||||
* Represents the different types of errors to be reported.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MONO_EMBEDDINATOR_OK = 0,
|
||||
// Mono managed exception
|
||||
MONO_EMBEDDINATOR_EXCEPTION_THROWN,
|
||||
// Mono failed to load assembly
|
||||
MONO_EMBEDDINATOR_ASSEMBLY_OPEN_FAILED,
|
||||
// Mono failed to lookup method
|
||||
MONO_EMBEDDINATOR_METHOD_LOOKUP_FAILED
|
||||
} mono_embeddinator_error_type_t;
|
||||
|
||||
/**
|
||||
* Represents the error type and associated data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
mono_embeddinator_error_type_t type;
|
||||
// Contains exception object if type is MONO_EMBEDDINATOR_EXCEPTION_THROWN
|
||||
MonoException* exception;
|
||||
const char* string;
|
||||
} mono_embeddinator_error_t;
|
||||
|
||||
/**
|
||||
* Fires an error and calls the installed error hook for handling.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void mono_embeddinator_error(mono_embeddinator_error_t error);
|
||||
|
||||
/** Represents the error report hook function type. */
|
||||
typedef void (*mono_embeddinator_error_report_hook_t)(mono_embeddinator_error_t);
|
||||
|
||||
/**
|
||||
* Installs an hook that is called for each error reported.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void* mono_embeddinator_install_error_report_hook(mono_embeddinator_error_report_hook_t hook);
|
||||
|
||||
/**
|
||||
* Arrays
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GArray* array;
|
||||
} MonoEmbedArray;
|
||||
|
||||
/**
|
||||
* Objects
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MonoClass* _class;
|
||||
uint32_t _handle;
|
||||
} MonoEmbedObject;
|
||||
|
||||
/**
|
||||
* Creates a MonoEmbedObject support object from a Mono object instance.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void* mono_embeddinator_create_object(MonoObject* instance);
|
||||
|
||||
/**
|
||||
* Initializes a MonoEmbedObject object from a Mono object instance.
|
||||
*/
|
||||
MONO_EMBEDDINATOR_API
|
||||
void mono_embeddinator_init_object(MonoEmbedObject* object, MonoObject* instance);
|
||||
|
||||
MONO_EMBEDDINATOR_END_DECLS
|
Двоичный файл не отображается.
|
@ -0,0 +1,15 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#include "mono_embeddinator.h"
|
||||
#include "bindings.h"
|
||||
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
int counter = argc == 1 ? 1000000 : atoi (argv [0]);
|
||||
|
||||
for (int i = 0; i < counter; i++) {
|
||||
assert (![Platform isWindows]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
Двоичный файл не отображается.
|
@ -0,0 +1,15 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#include "mono_embeddinator.h"
|
||||
#include "bindings.h"
|
||||
|
||||
int main ()
|
||||
{
|
||||
@autoreleasepool {
|
||||
NSLog (@"%s static property getter only", [Platform isWindows] ? "[FAIL]" : "[PASS]");
|
||||
|
||||
NSLog (@"%s static property getter", [Platform exitCode] == 0 ? "[PASS]" : "[FAIL]");
|
||||
Platform.exitCode = 255;
|
||||
NSLog (@"%s static property setter check", [Platform exitCode] == 255 ? "[PASS]" : "[FAIL]");
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using ObjC;
|
||||
|
||||
namespace ObjCGeneratorTest {
|
||||
|
||||
[TestFixture]
|
||||
public class Helpers {
|
||||
|
||||
[Test]
|
||||
public void CamelCase ()
|
||||
{
|
||||
Assert.Null (ObjCGenerator.CamelCase (null), "null");
|
||||
Assert.That (ObjCGenerator.CamelCase (String.Empty), Is.EqualTo (""), "length == 0");
|
||||
Assert.That (ObjCGenerator.CamelCase ("S"), Is.EqualTo ("s"), "length == 1");
|
||||
Assert.That (ObjCGenerator.CamelCase ("TU"), Is.EqualTo ("tU"), "length == 2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TypeMatch ()
|
||||
{
|
||||
Assert.That (ObjCGenerator.GetTypeName (typeof (bool)), Is.EqualTo ("bool"), "bool");
|
||||
Assert.That (ObjCGenerator.GetTypeName (typeof (int)), Is.EqualTo ("int"), "int");
|
||||
Assert.That (ObjCGenerator.GetTypeName (typeof (object)), Is.EqualTo ("NSObject"), "object");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{076A871B-0C13-47D8-8923-B9242995BFF8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>objcgentest</RootNamespace>
|
||||
<AssemblyName>objcgentest</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="nunit.framework">
|
||||
<HintPath>..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ObjCGeneratorTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\objcgen\objcgen.csproj">
|
||||
<Project>{C166803B-011F-4EAF-B8C2-D7DBBA3CF1EC}</Project>
|
||||
<Name>objcgen</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче