summaryrefslogtreecommitdiff
path: root/src/bindings/mono/eo_mono/FunctionWrapper.cs
blob: d42f1e3f3240f40e6c265169ecd0e0a398dba5e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using System;
using System.Runtime.InteropServices;

namespace Efl { namespace Eo {

public partial class FunctionInterop
{
    public static IntPtr LoadFunctionPointer(string moduleName, string functionName)
    {
        NativeModule module = new NativeModule(moduleName);
        Console.WriteLine("searching {0} in library {1}", module.Module, functionName);
        var s = FunctionInterop.dlsym(module.Module, functionName);
        Console.WriteLine("searching {0} in library {1}, result {2}", module.Module, functionName, s);
        return s;
    }
    public static IntPtr LoadFunctionPointer(string functionName)
    {
        Console.WriteLine("searching {0} in library {1}", null, functionName);
        var s = FunctionInterop.dlsym(IntPtr.Zero, functionName);
        Console.WriteLine("searching {0} in library {1}, result {2}", null, functionName, s);
        return s;
    }
}
        
public class FunctionWrapper<T>
{
    private Lazy<FunctionLoadResult<T>> loadResult;
    private NativeModule module; // so it doesn't get unloaded

    private static FunctionLoadResult<T> LazyInitialization(NativeModule module, string functionName)
    {
        if (module.Module == IntPtr.Zero)
            return new FunctionLoadResult<T>(FunctionLoadResultKind.LibraryNotFound);
        else
        {
            IntPtr funcptr = FunctionInterop.LoadFunctionPointer(module.Module, functionName);
            if (funcptr == IntPtr.Zero)
                return new FunctionLoadResult<T>(FunctionLoadResultKind.FunctionNotFound);
            else
                return new FunctionLoadResult<T>(Marshal.GetDelegateForFunctionPointer<T>(funcptr));
        }
    }
    
    public FunctionWrapper(string moduleName, string functionName)
        : this (new NativeModule(moduleName), functionName)
    {
    }
    
    public FunctionWrapper(NativeModule module, string functionName)
    {
        this.module = module;
        loadResult = new Lazy<FunctionLoadResult<T>>
            (() =>
            {
                return LazyInitialization(module, functionName);
            });
    }

    public FunctionLoadResult<T> Value
    {
        get
        {
            return loadResult.Value;
        }
    }
}

public enum FunctionLoadResultKind { Success, LibraryNotFound, FunctionNotFound }
    
public class FunctionLoadResult<T>
{
    public FunctionLoadResultKind Kind;
    public T Delegate;

    public FunctionLoadResult(FunctionLoadResultKind kind)
    {
        this.Kind = kind;
    }
    public FunctionLoadResult(T Delegate)
    {
        this.Delegate = Delegate;
        this.Kind = FunctionLoadResultKind.Success;
    }
}


} }