How Can My Code Access "Global" or "Module-Level" Methods from C#?
-
I've played with .NET/CLI for a while and have started learning MSIL/CIL.The following code compiles to a .NET executable without warning or error messages. ILASM reports in its output "Assembled global method HelloWorld."
.module HelloWorld.exe
.assembly extern mscorlib {}
.assembly MyAssembly
{
.ver 1: 0: 0: 0 /* Spaces because of smiley face replacement */
}.method public hidebysig static void HelloWorldHelper() cil managed
{
ldstr "Hello, World!"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}.class public auto ansi HelloWorld
extends [mscorlib]System.Object
{
.method public hidebysig static void HelloWorld() cil managed
{
.entrypoint
call void HelloWorldHelper()
ret
}
}My question: how can consuming C# code access the HelloWorldHelper method? For example:
/* consumer.cs */
public class Program
{
public static void Main(string[] args)
{
HelloWorldHelper();
}
}
/* end consumer.cs */will fail to compile with "csc /r:HelloWorld.exe consumer.cs" with "error CS0103: The name 'HelloWorldHelper' does not exist in the current context." (In case you wonder why I care about this arcane use, I am writing a compiler that targets the .NET run time.)
"we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
-
I've played with .NET/CLI for a while and have started learning MSIL/CIL.The following code compiles to a .NET executable without warning or error messages. ILASM reports in its output "Assembled global method HelloWorld."
.module HelloWorld.exe
.assembly extern mscorlib {}
.assembly MyAssembly
{
.ver 1: 0: 0: 0 /* Spaces because of smiley face replacement */
}.method public hidebysig static void HelloWorldHelper() cil managed
{
ldstr "Hello, World!"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}.class public auto ansi HelloWorld
extends [mscorlib]System.Object
{
.method public hidebysig static void HelloWorld() cil managed
{
.entrypoint
call void HelloWorldHelper()
ret
}
}My question: how can consuming C# code access the HelloWorldHelper method? For example:
/* consumer.cs */
public class Program
{
public static void Main(string[] args)
{
HelloWorldHelper();
}
}
/* end consumer.cs */will fail to compile with "csc /r:HelloWorld.exe consumer.cs" with "error CS0103: The name 'HelloWorldHelper' does not exist in the current context." (In case you wonder why I care about this arcane use, I am writing a compiler that targets the .NET run time.)
"we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
What would you expect to happen here? Your Main calls HelloWorldHelper which does not exist as a static method in the Program class.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
-
What would you expect to happen here? Your Main calls HelloWorldHelper which does not exist as a static method in the Program class.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
Don't worry. I just did some more research and found that cross-assembly global references are not supported. I did this through writing MSIL code to consume the global function in another assembly and received a compile error informing me of this issue. For anyone interested, here's the code and command lines:
/* File: helloworld.il */
.assembly extern mscorlib {}
.assembly helloworld
{
.ver 1: 0: 0: 0 /* Remove spaces for compilation. They make smilies on CP. */
}.method public static void HelloWorld()
{
ldstr "Hello World!"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}Compile with
ilasm /DLL helloworld.il
/* File: printer.il */
.assembly extern mscorlib {}
.assembly extern helloworld
{
.ver 1: 0: 0: 0 /* Remove spaces for compilation. They make smilies on CP. */
}.assembly Moo
{
.ver 1: 0: 0: 0 /* Remove spaces for compilation. They make smilies on CP. */
}.class public auto ansi Program extends [mscorlib]System.Object
{
.method public hidebysig static void Main() cil managed
{
.entrypoint
call void [helloworld]::HelloWorld()
ret
}
}Compile with
ilasm printer.il
You will receive something similar to the following error:Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.3053
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'printer.il' to EXE --> 'printer.exe'
Source file is ANSIprinter.il(17) : error -- Cross-assembly global references are not supported ('HelloWorld')
Assembled method Program::Main***** FAILURE *****
"we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty