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