0

I am currently using this post as a guide How to create multi-dimensional array using Reflection.Emit but using a single dimensional array.

My function looks like

public void CallMethod3(object[] Items)
{

}

and my reflection emit code looks like

MethodInfo invokerMethod = typeof(Foo).GetMethod("CallMethod3");
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ldarg_0);

// var local = new int[1];
LocalBuilder local = il.DeclareLocal(typeof(object[]));
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Newobj, typeof(object[]).GetConstructor(new[] { typeof(int) }));
il.Emit(OpCodes.Stloc, local);

// il.Emit(OpCodes.Ldloc, local);
// il.Emit(OpCodes.Ldc_I4_0);
// il.Emit(OpCodes.Ldc_I4, 123);
// var setMethod = typeof(object[]).GetMethod("Set");
// il.Emit(OpCodes.Call, setMethod);

il.Emit(OpCodes.Ldloc, local);

il.Emit(OpCodes.Call, invokerMethod);
il.Emit(OpCodes.Ret);

Everything works fine and I can hit the breakpoint at the method. However, I start facing problem when I try to populate the object array (code commented out here). I start getting invalid invocations.

Any idea what I am doing wrong?

Filburt
  • 17,626
  • 12
  • 64
  • 115
Grimson
  • 540
  • 1
  • 5
  • 21
  • If you're creating a one-dimensional array, why not use [`newarr`](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.newarr)? – madreflection Jan 06 '20 at 21:30
  • I'm no IL expert, but Array doesn't have a `Set` method. Are you looking for `SetValue`? – StriplingWarrior Jan 06 '20 at 21:31
  • @StriplingWarrior: One of the `stelem` instructions would be better. – madreflection Jan 06 '20 at 21:33
  • Yeah, like [stelem.ref](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stelem_ref?view=netframework-4.8) – StriplingWarrior Jan 06 '20 at 21:33
  • @madreflection I used the link as the guide, hence I used newobj – Grimson Jan 06 '20 at 21:34
  • The linked solution is over-engineered for a single dimension because multiple dimensions require more work. – madreflection Jan 06 '20 at 21:34
  • @StriplingWarrior AFAIK, I assumed Set would be available just as it is in the guide – Grimson Jan 06 '20 at 21:35
  • @madreflection Can you post an answer? I'll quickly give it a try – Grimson Jan 06 '20 at 21:35
  • 1
    Here's a general-purpose tip: try putting the code you want to produce into LINQPad and switch to the IL tab. That can help you see what instructions you actually want, and work your way back from there. – StriplingWarrior Jan 06 '20 at 21:36
  • 2
    Or try [this](https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgJgIwFgBQyDMABGgQMIEDeOB1RhyALAQLIAUAlBVTdwG4CGAJwIQA9gGM+EAgF4CAOwCmAdwIiARgCsFY4AG10AXQDcXbtVESIugAwGZBdKjwnsZmiUkQmC4AAsRMHgsFpJsLtwAvqYE0fhEjB4QXj7+gSzqWjq6dgCSwAoAtgDObNGUrjRR2BFAA=). :) – yaakov Jan 06 '20 at 21:45
  • @yaakov The reason why I am not going for that approach is because I am trying to generate proxies on the fly. – Grimson Jan 06 '20 at 21:48
  • @StriplingWarrior I could never understand box and stelem ref. Could you tell me what they are used for? – Grimson Jan 06 '20 at 21:50
  • 1
    @Crimson7: yaakov is simply suggesting that you use SharpLab.io (as an alternative to LINQPad) to figure out what IL opcodes to use to generate your proxies on the fly, not that you write static code. – madreflection Jan 06 '20 at 22:00
  • I cannot. As I said, I am not an IL expert. The only way I'm able to make it look like I know anything is that I've gotten really good at using LINQPad and Google. I used LINQPad to see what instructions appear, and then I used google to find the docs for those instructions. The docs that I linked to say "Replaces an array element at the supplied index with the `ref` value (type O) on the stack." Comparing that with other stelem instructions, and comparing the LINQPad output when I change the array type to `int[]`, I'm guessing `object`s have a `ref` type, so you have to use `stelem.ref` here. – StriplingWarrior Jan 06 '20 at 22:21
  • I gotta say, SharpLab really made my work a lot easier. Thanks @yaakov. Plus I also looked into documentation for those OpCodes, and they make a lot more sense now. Thanks everyone! – Grimson Jan 07 '20 at 13:50

0 Answers0