Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DynamicMethod Byref Return Type #26657

Closed
mikernet opened this issue Jun 29, 2018 · 4 comments
Closed

DynamicMethod Byref Return Type #26657

mikernet opened this issue Jun 29, 2018 · 4 comments

Comments

@mikernet
Copy link
Contributor

Would like to be able to set a ref return type like this:

var method = new DynamicMethod("Method", typeof(object).MakeByRefType(), new[] { typeof(object) }, ownerType, true);

Currently have to use this workaround/hack to avoid exception being thrown:

var method = new DynamicMethod("Method", typeof(object), new[] { typeof(object) }, ownerType, true);
method.GetType().GetField("m_returnType", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).SetValue(method, typeof(object).MakeByRefType());
@mgravell
Copy link
Member

mgravell commented Jun 29, 2018

Interestingly, this limitation only applies to DynamicMethod. If you use TypeBuilder, you can create a by-ref return method:

delegate ref object SomeDelegateType(object[] arr);
...
var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(
    new AssemblyName("foo"), AssemblyBuilderAccess.Run);
var module = asm.DefineDynamicModule("foo");
var tb = module.DefineType("bar", TypeAttributes.Class, typeof(object));
var mb = tb.DefineMethod("method",
      MethodAttributes.Public | MethodAttributes.Static,
      typeof(object).MakeByRefType(), new Type[] { typeof(object[]) });
var il = mb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Ldelema, typeof(object));
il.Emit(OpCodes.Ret);

var type = tb.CreateType();
var method = type.GetMethod("method");
var del = (SomeDelegateType)Delegate.CreateDelegate(typeof(SomeDelegateType), null, method);

object[] arr = new object[4] { "abc", "def", "ghi", "jkl" };

ref object r = ref del(arr);
Console.WriteLine(r); // ghi

The custom delegate here is required because you can't invoke this type of method via reflection, since a managed pointer (ref object in this case) can not be boxed.

@mikernet
Copy link
Contributor Author

Yeah, the Init() method in DynamicMethod explicitly checks if the return type is byref and throws if it is.

@jkotas
Copy link
Member

jkotas commented Jun 29, 2018

This was fixed by dotnet/coreclr#15106 . This fix is included in .NET Core 2.1

@jkotas jkotas closed this as completed Jun 29, 2018
@mikernet
Copy link
Contributor Author

Oh my mistake...I looked though "DynamicMethod" issues but it didn't come up because of the space between the words in the other issue :/

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants