Click here to Skip to main content
13,350,708 members (57,918 online)
Click here to Skip to main content
Add your own
alternative version


36 bookmarked
Posted 12 Aug 2012

Exporting functions in C#/VB.NET to native code

, 19 Nov 2012
Rate this:
Please Sign up or sign in to vote.
Discusses how to export methods in C#/VB.NET to be used in native code (such as C/C++)


The following article discusses how one would achieve exporting a function from C#/VB.NET code to be used in native code (such as C/C++). I've seen a few methods around the internet about doing this, but most of them require you to tediously add things to your project to identify methods that will be exported, such as this. With that, these articles inspired this project which is an extension of the IL-compiler from one of my previous articles.

How it works

As I previously mentioned, this article is built upon one of my previous articles (link above). This required the InlineILCompiler.exe tool from the previous article. The way this works is I have modified InlineILCompiler.exe to add a new directive which I called .exportnative. This directive marks methods so that the tool knows what to export.

Here's how the magic works: Find out how many methods are being invoked. Once this is done, we add .vtfixup directives and .data directives for each function. With only one method being exported, here's a sample:

.vtfixup [1] int32 fromunmanaged at VT1
.data VT1 = int32(0) 

According to this, it's also important to note that the .corflags directive needs to be changed to 2. I haven't actually tested if it works without this, but as far as I could see, Delphi .NET uses this corflag as well when exporting functions so I assumed it was required.

.corflags 0x00000002 

According to what I saw in Delphi.NET as well, a method must also apply a modopt() declaring a calling convention. I chose to always use stdcall as a standard. So, we end up with an exported method having the following definition:

.method public hidebysig static void  modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) DllMain() cil managed

Inside of that method, we need to declare the virtual table entry it is associated with as well as the export entry and name.

.vtentry 1 : 1
.export [1] as DllMain 

This is done for every method being exported which is all handled automatically by InlineILCompiler.exe.


Exporting a method is incredibly easy. I'm not going to provide any elaborate guides about marshalling between native code and managed code as I think you can find other articles which cover this fairly well. As a rule of thumb, your methods shouldn't return anything greater than 4 bytes (int), anything larger than that should be passed using a ref or out parameter.

It's important to note that the name you use with .exportnative must be the same as the .NET function's name and that method must be static.

Here's an example of an exported function (C#):

public struct Foo
    public int A;
        public int B;
        public int C;

public static void CreateFoo(out Foo foo)
#if IL
    .exportnative CreateFoo
        foo = new Foo();
        foo.A = 22;
        foo.B = 44;
        foo.C = 55;

And now, here's using the code (C):

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <Windows.h>

struct Foo_t
    int32_t A;
    int32_t B;
    int32_t C;

typedef void (__stdcall *LPFCREATEFOO)(struct Foo_t *foo);

int main(void)
    HMODULE mod;
    struct Foo_t foo;

    mod = LoadLibraryA("ExportNativeTest.dll");
    CreateFoo = (LPFCREATEFOO)GetProcAddress(mod, "CreateFoo");
    printf("%d %d %d\r\n", foo.A, foo.B, foo.C);

    return 0;

Closing Remarks

I find it kind of disappointing Microsoft has a standardized DllImport attribute but not a standardized a DllExport attribute and such hacks need to be developed to achieve it. I expected .NET 4.5 to have such an attribute, but alas it did not which was disappointing as it doesn't seem like they will be adding one anytime soon. I currently have not tested the limitations of using these natively exported methods, so if anyone would like to provide any feedback about bugs, etc., it would be greatly appreciated. I hope you enjoyed the article and learned something new or useful.


  • Sunday, August 12, 2012: Initial release.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Canada Canada
I was born March 15th 1994 and I have been programming for about 5 years now and working with C# for about 3 years. I am experienced in a variety of programming languages such as C/C++, Delphi, VB.NET, F#, and Python. I absolutely love learning new things about computer science, so I'm always doing research and often reinventing the wheel to get a better grasp on concepts.

You may also be interested in...


Comments and Discussions

QuestionUsing C# class Pin
Davide Zaccanti24-Aug-12 8:04
memberDavide Zaccanti24-Aug-12 8:04 
AnswerRe: Using C# class Pin
roylawliet24-Aug-12 8:57
memberroylawliet24-Aug-12 8:57 
GeneralRe: Using C# class Pin
Davide Zaccanti26-Aug-12 21:09
memberDavide Zaccanti26-Aug-12 21:09 
QuestionNice Pin
CIDev16-Aug-12 5:34
memberCIDev16-Aug-12 5:34 
GeneralMy vote of 5 Pin
bitterskittles15-Aug-12 7:56
memberbitterskittles15-Aug-12 7:56 
GeneralRe: My vote of 5 Pin
roylawliet15-Aug-12 16:53
memberroylawliet15-Aug-12 16:53 
GeneralCool Tool, but ... Pin
ernie100014-Aug-12 0:56
memberernie100014-Aug-12 0:56 
GeneralRe: Cool Tool, but ... Pin
roylawliet14-Aug-12 3:13
memberroylawliet14-Aug-12 3:13 
GeneralRe: Cool Tool, but ... Pin
ernie100014-Aug-12 4:01
memberernie100014-Aug-12 4:01 
GeneralRe: Cool Tool, but ... Pin
roylawliet14-Aug-12 9:46
memberroylawliet14-Aug-12 9:46 
GeneralRe: Cool Tool, but ... Pin
ernie100014-Aug-12 21:40
memberernie100014-Aug-12 21:40 
GeneralMy vote of 5 Pin
bartolo13-Aug-12 1:46
memberbartolo13-Aug-12 1:46 
QuestionA notice for viewers on August 12 2012 Pin
roylawliet12-Aug-12 14:51
memberroylawliet12-Aug-12 14:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.180111.1 | Last Updated 19 Nov 2012
Article Copyright 2012 by roylawliet
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid