Hello Jb,

I have successfully modified the Mono.Cecil code source in order to
manage exporting from external module.

Here are my suggested modifications:
1. in ModuleDefinition class, add a OwnerAssembly property that return
the assembly field ifnot set, else return the set value :

        AssemblyDefinition owningAssembly;
        public AssemblyDefinition OwningAssembly
        {
            get { return assembly ?? owningAssembly; }
            set { owningAssembly = value; }
        }

2. in ModuleDefinition class, add a CreateModule method with the
owning AssemblyDefinition passed as parameter :

        public static ModuleDefinition CreateModule(string name,
ModuleParameters parameters, AssemblyDefinition assembly)
        {
            ModuleDefinition module = CreateModule(name, parameters);
            module.OwningAssembly = assembly;
            return module;
        }

3. in Import.cs, method ImportScope, check the owning assembly in case
of MetadataScopeType.ModuleDefinition :


        IMetadataScope ImportScope(IMetadataScope scope)
        {
                        switch (scope.MetadataScopeType) {
                case MetadataScopeType.AssemblyNameReference:
                    return
ImportAssemblyName((AssemblyNameReference)scope);
                case MetadataScopeType.ModuleDefinition:
                    >>>if (((ModuleDefinition)scope).OwningAssembly ==
module.OwningAssembly)
                        return
ImportModule(((ModuleDefinition)scope).Name);
                    return
ImportAssemblyName(((ModuleDefinition)scope).OwningAssembly.Name);<<<   !!!
modified part !!!
                case MetadataScopeType.ModuleReference:
                    throw new NotImplementedException();
            }

            throw new NotSupportedException();
        }

4. in import.cs, define the missing methods :

        ModuleReference ImportModule(string name)
        {
            ModuleReference reference;
            if (TryGetModuleReference(name, out reference))
                return reference;

            reference = new ModuleReference(name);

            module.ModuleReferences.Add(reference);

            return reference;
        }

        bool TryGetModuleReference(string name_reference, out
ModuleReference module_reference)
        {
            var references = module.ModuleReferences;

            for (int i = 0; i < references.Count; i++)
            {
                var reference = references[i];
                if (name_reference != reference.Name)
                    continue;

                module_reference = reference;
                return true;
            }

            module_reference = null;
            return false;
        }

And it works!

On 10 sep, 14:06, Jb Evain <[email protected]> wrote:
> Hey,
>
>
>
> On Fri, Sep 10, 2010 at 2:01 PM, Regis <[email protected]> wrote:
> > I want to create an AssemblyDefinition with two modules : the manifest
> > m0 plus an external module m1.
>
> > If I define the body of the entry point of my assembly in order to
> > call a method in a class defined in my external module, do I have to
> > call
>
> > _il.Emit(OpCodes.Call, m0.Import(myExternalMethod))
>
> > or
>
> > _il.Emit(OpCodes.Call, myExternalMethod) ?
>
> > In fact, as it is the same assembly but another module, I am not sure
> > what to do.
>
> Import doesn't support multiple modules assemblies. But you can't use
> a definition from another module directly. So you have to create
> references, and use a proper ModuleReference as a scope.
>
> --
> Jb EvainĀ  <[email protected]>

-- 
--
mono-cecil

Reply via email to