Ejemplo n.º 1
0
        // Creates implementation of a given interface for wrapping function the specified DLL
        WrappedInterface createInterface <IT>(string dll_name) where IT : class
        {
            WrappedInterface result = new WrappedInterface();

            Type         itype = typeof(IT);
            AppDomain    cd    = System.Threading.Thread.GetDomain();
            AssemblyName an    = new AssemblyName();

            an.Name = itype.Name + "_" + dll_name.Replace('.', '_');
            AssemblyBuilder ab = cd.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            ModuleBuilder   mb = ab.DefineDynamicModule(an.Name, false);
            TypeBuilder     tb = mb.DefineType(an.Name, TypeAttributes.Class |
                                               TypeAttributes.Public);

            tb.AddInterfaceImplementation(itype);

            IntPtr dll_handle = _loaded_dlls[dll_name].handle;

            Dictionary <List <Type>, Type> signature_to_name =
                new Dictionary <List <Type>, Type>(new TypeListComparer());

            // Set delegate references
            foreach (MethodInfo m in itype.GetMethods())
            {
                ParameterInfo[] parameters = m.GetParameters();
                Type[]          arg_types  = new Type[parameters.Length];
                for (int i = 0; i < parameters.Length; i++)
                {
                    arg_types[i] = parameters[i].ParameterType;
                }

                Type delegate_ret_type = m.ReturnType;
                if (delegate_ret_type == typeof(String))
                {
                    delegate_ret_type = typeof(sbyte *);
                }

                List <Type> signature = new List <Type>();
                signature.Add(delegate_ret_type);
                signature.AddRange(arg_types);

                Type call_delegate = null;
                if (!signature_to_name.TryGetValue(signature, out call_delegate))
                {
                    // Check if type was already created
                    string delegate_type_name = String.Format("delegate_{0}", signature_to_name.Count);
                    call_delegate = createDelegateType(delegate_type_name, mb, delegate_ret_type, arg_types);
                    signature_to_name.Add(signature, call_delegate);
                }

                string       delegate_field_name = m.Name + "_ptr";
                FieldBuilder delegate_field      =
                    tb.DefineField(delegate_field_name, typeof(Delegate), FieldAttributes.Private);

                IntPtr proc = LibraryLoader.GetProcAddress(dll_handle, m.Name);
                if (proc == IntPtr.Zero)
                {
                    throw new IndigoException(String.Format("Cannot find procedure {0} in the library {1}",
                                                            m.Name, dll_name));
                }
                Delegate proc_delegate = Marshal.GetDelegateForFunctionPointer(proc, call_delegate);
                result.delegates.Add(delegate_field_name, proc_delegate);

                MethodBuilder meth = tb.DefineMethod(m.Name,
                                                     MethodAttributes.Public | MethodAttributes.Virtual, m.ReturnType, arg_types);

                ILGenerator il = meth.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, delegate_field);
                for (int i = 1; i < arg_types.Length + 1; i++)
                {
                    il.Emit(OpCodes.Ldarg, i);
                }
                MethodInfo infoMethod = proc_delegate.GetType().GetMethod("Invoke", arg_types);
                il.EmitCall(OpCodes.Callvirt, infoMethod, null);
                // Automatically convert sbyte* to String
                if (m.ReturnType == typeof(String))
                {
                    Type            str_type = typeof(String);
                    ConstructorInfo ci       = str_type.GetConstructor(new Type[] { typeof(sbyte *) });
                    il.Emit(OpCodes.Newobj, ci);
                }
                il.Emit(OpCodes.Ret);

                tb.DefineMethodOverride(meth, m);
            }

            // ab.Save(an.Name + ".dll");

            Type impl_class = tb.CreateType();
            IT   impl       = (IT)Activator.CreateInstance(impl_class);

            // Set references to the delegates
            foreach (string field_name in result.delegates.Keys)
            {
                impl_class.GetField(field_name, BindingFlags.Instance | BindingFlags.NonPublic)
                .SetValue(impl, result.delegates[field_name]);
            }

            result.instance = impl;
            return(result);
        }
Ejemplo n.º 2
0
        public void loadLibrary(String path, String dll_name, string resource_name, bool make_unique_dll_name)
        {
            lock (_sync_object)
            {
                DllData data = null;
                if (_loaded_dlls.TryGetValue(dll_name, out data))
                {
                    // Library has already been loaded
                    if (data.lib_path != path)
                    {
                        throw new IndigoException(
                                  String.Format("Library {0} has already been loaded by different path {1}",
                                                dll_name, data.lib_path)
                                  );
                    }
                    return;
                }

                String subprefix = null;

                switch (Environment.OSVersion.Platform)
                {
                case PlatformID.Win32NT:
                    subprefix = (IntPtr.Size == 8) ? "Win/x64/" : "Win/x86/";
                    break;

                case PlatformID.Unix:
                    if (isMac())
                    {
                        subprefix = "Mac/10.6/";
                    }
                    else
                    {
                        subprefix = (IntPtr.Size == 8) ? "Linux/x64/" : "Linux/x86/";
                    }
                    break;

                default:
                    throw new PlatformNotSupportedException(String.Format(
                                                                "Unsupported platform: {0}",
                                                                Environment.OSVersion.Platform
                                                                )
                                                            );
                }

                data           = new DllData();
                data.lib_path  = path;
                data.file_name = _getPathToBinary(path, subprefix + dll_name,
                                                  resource_name, Assembly.GetCallingAssembly(), make_unique_dll_name);

                data.file_name = data.file_name.Replace('/', '\\');

                data.handle = LibraryLoader.LoadLibrary(data.file_name);

                if (data.handle == IntPtr.Zero)
                {
                    throw new Exception("Cannot load library " + dll_name +
                                        " from the temporary file " + data.file_name
                                        );
                }

                _loaded_dlls.Add(dll_name, data);

                _dll_handles.Add(data);
            }
        }