_(The title nearly says it all)_
I would like to propose the ability to export a function written in a C#-project to native code (C++ etc.) -- quasi the opposite of a P/Invoke-call.
As the CLR has this already implemented (See Serge Lindin's book about the .NET 2.0 Assembler, chapter 18, pages 380 and following) since v2.0, no CLR changes have to be made for this feature.
An "exported" function must be marked as static
and should be non-private. A possible example could be:
public static export int Add(int a, int b)
{
return a + b;
}
which would compile into something like this:
.corflags 0x00000002
.vtfixup [1] int32 fromunmanaged at VT_01
.data VT_01 = int32(0)
...
.method public static int32 Add(int32 a, int32 b) // notice the lack of the 'cil managed' keyword
{
.vtentry 1:1
.export [1]
.maxstack 2
ldarg.0
ldarg.1
add
ret
}
which could be called from other (native) asseblies.
If one would like to export the function under a different name (e.g. as MyAdd
instead of Add
), it could be done as follows:
public static export "MyAdd" int Add(int a, int b) { ... }
Which would result in the following CIL-code:
.corflags 0x00000002
.vtfixup [1] int32 fromunmanaged at VT_01
.data VT_01 = int32(0)
...
.method public static int32 Add(int32 a, int32 b) // notice the lack of the 'cil managed' keyword
{
.vtentry 1:1
.export [1] as MyAdd
...
}
Of course, all parameters and return values must be value types (native arrays, primitives, native structures or pointer).
For exporting constants, see this post
I know, that the the project Unmanaged Exports
by Robert Giesecke exists, however I would like to see this feature implemented into the C#-language without the need of external references or extensions.
Personally, I think that rather than a new keyword that I'd rather see another pseudo-attribute, DllExportAttribute
:
[DllExport(ExportAs = "MyAdd")]
public static int Add(int x, int y) {
return x + y;
}
@HaloFour: Yes, you are probably right with an (pseudo-)attribute usage to keep consistency with the DllImport
-Attribute.
Come to think of it, it would be easier to port code, which used the Unmanaged Exports
-project previously, as the syntax would remain the same,
Similar feature request already exists: https://github.com/dotnet/roslyn/issues/1013. And yes, would be nice to have such feature.
@tomrus88: Thank you very much Sir for mentioning it... I will look into the linked reference
Attributes like this are why I was hoping Roslyn would have given us a compiler pipeline. Injecting extra extensions in such a case would be childs play
(See Serge Lindin's book about the .NET 2.0 Assembler, chapter 18, pages 380 and following) since v2.0
Quote from page 386:
The good news is that version 2.0 of the IL assembler does not require these directives at
all, as long as the v-table and VTFixup table are used for unmanaged exports only. Just specify
the.export
directives in the methods you want to export to the unmanaged world, and the
flags, the v-table, and its fixups will be generated automatically by the compiler, with the slot
size adjusted for the target platform
Well, just .export
directive must be injected/inserted and that's it (assuming a program has to be built for either x64 or x86 target processor). Additionally, modopt
could be injected/inserted to set specific calling convention (when it is marshaled as unmanaged):
.method public static void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) Foo()
{
.export [1] as Bar // Export #1, Name="Bar"
// ...
}
That's all I have wanted to point out here. I hope one day C#/VB will have this.
@OmegaExtern : I always use the IL Support extension for VS, but that is a bit tedious. I also hope that VB/C#/F#/J#/ ..... will have this feature
FYI, https://github.com/dotnet/roslyn/issues/1013 is also a duplicate of this.
I'd love to see this.
There is something, which I have forgotten to mention while creating this issue:
What about exporting constants?
In C++, you can do something like this:
extern "C" __declspec(dllexport) static DWORD MyConstant = 0x00000042;
Is this possible to do in C#?
It could be written as
[DllExport]
public const int MyConstant = 0x00000042;
I think the required CIL code is something along these lines:
.field public static int32 MyConstant at data_01
...
.data data_01 = int32(0x00000042)
This could help me a lot by writing
[DllExport]
public const int NvOptimusEnablement = 1;
instead of
.data data_01 = int32(1)
.class public auto ansi '<Module>'
{
.field public static int32 NvOptimusEnablement at data_01
}
every time I need NVidia-Optimus-support for my .NET executable
Most helpful comment
Personally, I think that rather than a new keyword that I'd rather see another pseudo-attribute,
DllExportAttribute
: