Howdy!
I posted this question on CSharpCorner.co m, but then realized I should
probably post it on a more active newsgroup. This will be my only cross-post.
I'm creating a game engine, and using CodeDOM for my scripting needs (I
realize I could use yacc or something else, but I wanted to try using CodeDOM
-- this is more of an exercise for me to learn this stuff).
Well, I compile my in-game scripts just fine. See appendix A for my code
that does that (it was too cluttered to paste right here. Suffice to say, it
works)
I'm referencing my own executable, so that I can share code/types from my
main application.
Now, I go over and try to invoke the method from the assembly I just
compiled. The code that tries that looks like this:
object retObj = null;
object[] scriptParams = new object[1];
scriptParams[0] = context; // "context" is of type miteScriptConte xt, which
is what the method is expecting
retObj = script.ScriptMe thod.Invoke(scr ipt.asm, scriptParams);
However, it throws the following error for me:
"Unhandled Exception: System.Reflecti on.TargetExcept ion: Object does not
match target type."
So I'm thinking, "okay, I must be having a wrong parameter", but I checked
and double-checked and my code seems correct. *FINALLY* I wrote the following
debug code:
object[] scriptParams = new object[1];
scriptParams[0] = context;
Console.WriteLi ne("Method return type is: " +
script.ScriptMe thod.ReturnType .ToString());
Console.WriteLi ne("Passing in...");
Console.WriteLi ne(scriptParams[0].GetType().ToSt ring() + ": " +
scriptParams[0].GetHashCode(). ToString());
Console.WriteLi ne(scriptParams[0].GetType().Asse mbly.Location);
Console.WriteLi ne(scriptParams[0].GetType().Asse mbly.FullName);
Console.WriteLi ne();
Console.WriteLi ne("...into..." );
Console.WriteLi ne(script.Scrip tMethod.GetPara meters()[0].ParameterType. ToString()
+ ": " +
script.ScriptMe thod.GetParamet ers()[0].ParameterType. GetHashCode().T oString())
Console.WriteLi ne(script.Scrip tMethod.GetPara meters()[0].ParameterType. Assembly.Locati on)
Console.WriteLi ne(script.Scrip tMethod.GetPara meters()[0].ParameterType. Assembly.FullNa me);
Console.WriteLi ne();
retObj = script.ScriptMe thod.Invoke(scr ipt.asm, scriptParams);
That outputs the following...
Method return type is: System.Object
Passing in...
MITE.GameData.S cripting.miteSc riptContext: 4
C:\Documents and Settings\cherro n\My Documents\Sharp Develop
Projects\MITE\b in\Debug\MITE.e xe
MITE, Version=1.0.198 6.18485, Culture=neutral , PublicKeyToken= null
....into...
MITE.GameData.S cripting.miteSc riptContext: 202521200
C:\Documents and Settings\cherro n\My Documents\Sharp Develop
Projects\MITE\b in\Debug\MITE.e xe
MITE, Version=1.0.198 6.18485, Culture=neutral , PublicKeyToken= null
Okay. That's *REALLY* confusing to me. Basically it's saying that the types
don't match up. I'm passing in an object of type miteScriptConte xt. Both
types say that they come from the same assembly, from the same version,
everything. However, when referenced in different ways, that type comes up
with different hash codes?
Am I on crack, or is something wrong here? How can it be getting the same
type from the same assembly in two different ways and thinking that they're
different?
If anyone can point me in the right direction, that would be wonderful.
I know this method of calling scripts works, because I have another project
where I'm practicing the same method and it works just fine! I can't figure
out what's different about *this* project that makes it generate different
hash codes for the same type (which effectively makes Reflection think that
they're different types altogether). I would like to post a small sample app,
and if I need to create one, I can, it's just that there's a lot of overhead
involved, and it wouldn't be a very "small" app. :) I was hoping someone
would understand the theory of the way .NET determines if types are
compatible, and could help me out from a theory point of view.
Help, please? :)
Thanks!
Respectfully,
clint
Appendix A: My code to compile an assembly from code at runtime
public static Assembly CompileCode(str ing code)
{
Microsoft.CShar p.CSharpCodePro vider provider = new
Microsoft.CShar p.CSharpCodePro vider();
System.CodeDom. Compiler.ICodeC ompiler compiler = provider.Create Compiler();
System.CodeDom. Compiler.Compil erParameters param = new
System.CodeDom. Compiler.Compil erParameters();
System.CodeDom. Compiler.Compil erResults results;
param.GenerateI nMemory = true;
param.GenerateE xecutable = false;
param.Reference dAssemblies.Add (Assembly.GetEx ecutingAssembly ().Location);
results = compiler.Compil eAssemblyFromSo urce(param, code);
if (results.Errors .HasErrors)
{
string errText = "";
foreach (System.CodeDom .Compiler.Compi lerError err in results.Errors)
{
errText += ("Line [" + err.Line.ToStri ng() + "] :" + err.ErrorText + "\r\n");
}
// TODO: Better error reporting mechanism.
System.Windows. Forms.MessageBo x.Show(errText,
results.Errors. Count.ToString( ) + " errors");
return null;
}
return (results.Compil edAssembly);
}
I posted this question on CSharpCorner.co m, but then realized I should
probably post it on a more active newsgroup. This will be my only cross-post.
I'm creating a game engine, and using CodeDOM for my scripting needs (I
realize I could use yacc or something else, but I wanted to try using CodeDOM
-- this is more of an exercise for me to learn this stuff).
Well, I compile my in-game scripts just fine. See appendix A for my code
that does that (it was too cluttered to paste right here. Suffice to say, it
works)
I'm referencing my own executable, so that I can share code/types from my
main application.
Now, I go over and try to invoke the method from the assembly I just
compiled. The code that tries that looks like this:
object retObj = null;
object[] scriptParams = new object[1];
scriptParams[0] = context; // "context" is of type miteScriptConte xt, which
is what the method is expecting
retObj = script.ScriptMe thod.Invoke(scr ipt.asm, scriptParams);
However, it throws the following error for me:
"Unhandled Exception: System.Reflecti on.TargetExcept ion: Object does not
match target type."
So I'm thinking, "okay, I must be having a wrong parameter", but I checked
and double-checked and my code seems correct. *FINALLY* I wrote the following
debug code:
object[] scriptParams = new object[1];
scriptParams[0] = context;
Console.WriteLi ne("Method return type is: " +
script.ScriptMe thod.ReturnType .ToString());
Console.WriteLi ne("Passing in...");
Console.WriteLi ne(scriptParams[0].GetType().ToSt ring() + ": " +
scriptParams[0].GetHashCode(). ToString());
Console.WriteLi ne(scriptParams[0].GetType().Asse mbly.Location);
Console.WriteLi ne(scriptParams[0].GetType().Asse mbly.FullName);
Console.WriteLi ne();
Console.WriteLi ne("...into..." );
Console.WriteLi ne(script.Scrip tMethod.GetPara meters()[0].ParameterType. ToString()
+ ": " +
script.ScriptMe thod.GetParamet ers()[0].ParameterType. GetHashCode().T oString())
Console.WriteLi ne(script.Scrip tMethod.GetPara meters()[0].ParameterType. Assembly.Locati on)
Console.WriteLi ne(script.Scrip tMethod.GetPara meters()[0].ParameterType. Assembly.FullNa me);
Console.WriteLi ne();
retObj = script.ScriptMe thod.Invoke(scr ipt.asm, scriptParams);
That outputs the following...
Method return type is: System.Object
Passing in...
MITE.GameData.S cripting.miteSc riptContext: 4
C:\Documents and Settings\cherro n\My Documents\Sharp Develop
Projects\MITE\b in\Debug\MITE.e xe
MITE, Version=1.0.198 6.18485, Culture=neutral , PublicKeyToken= null
....into...
MITE.GameData.S cripting.miteSc riptContext: 202521200
C:\Documents and Settings\cherro n\My Documents\Sharp Develop
Projects\MITE\b in\Debug\MITE.e xe
MITE, Version=1.0.198 6.18485, Culture=neutral , PublicKeyToken= null
Okay. That's *REALLY* confusing to me. Basically it's saying that the types
don't match up. I'm passing in an object of type miteScriptConte xt. Both
types say that they come from the same assembly, from the same version,
everything. However, when referenced in different ways, that type comes up
with different hash codes?
Am I on crack, or is something wrong here? How can it be getting the same
type from the same assembly in two different ways and thinking that they're
different?
If anyone can point me in the right direction, that would be wonderful.
I know this method of calling scripts works, because I have another project
where I'm practicing the same method and it works just fine! I can't figure
out what's different about *this* project that makes it generate different
hash codes for the same type (which effectively makes Reflection think that
they're different types altogether). I would like to post a small sample app,
and if I need to create one, I can, it's just that there's a lot of overhead
involved, and it wouldn't be a very "small" app. :) I was hoping someone
would understand the theory of the way .NET determines if types are
compatible, and could help me out from a theory point of view.
Help, please? :)
Thanks!
Respectfully,
clint
Appendix A: My code to compile an assembly from code at runtime
public static Assembly CompileCode(str ing code)
{
Microsoft.CShar p.CSharpCodePro vider provider = new
Microsoft.CShar p.CSharpCodePro vider();
System.CodeDom. Compiler.ICodeC ompiler compiler = provider.Create Compiler();
System.CodeDom. Compiler.Compil erParameters param = new
System.CodeDom. Compiler.Compil erParameters();
System.CodeDom. Compiler.Compil erResults results;
param.GenerateI nMemory = true;
param.GenerateE xecutable = false;
param.Reference dAssemblies.Add (Assembly.GetEx ecutingAssembly ().Location);
results = compiler.Compil eAssemblyFromSo urce(param, code);
if (results.Errors .HasErrors)
{
string errText = "";
foreach (System.CodeDom .Compiler.Compi lerError err in results.Errors)
{
errText += ("Line [" + err.Line.ToStri ng() + "] :" + err.ErrorText + "\r\n");
}
// TODO: Better error reporting mechanism.
System.Windows. Forms.MessageBo x.Show(errText,
results.Errors. Count.ToString( ) + " errors");
return null;
}
return (results.Compil edAssembly);
}
Comment