Click here to Skip to main content
Click here to Skip to main content

How to Automate Exporting .NET Function to Unmanaged Programs

By , 21 Nov 2006
 

Introduction

Exporting functions to unmanaged programs - why not? I don't want to change *.il files by hand. I need to automate this. So here we go...

Background

A few days ago, I was writing a program (Terminal Services addin). The first problem was that I couldn't write this in C# ... Ok. I started writing it in C++/CLI. But there was another problem - mstsc.exe doesn't like to load such a library. Ok. No problem. I started another project (in C++/CLI - the first I change to pure C++) which exports one function. The first library loaded the second one and everything worked. But for dependencies, I needed easy deployment without installing VC80 runtimes... So I tried to find a way to export the function from C#. And I found it. While I was working with a project, I compiled it often and changing *.il files by hand was really annoying. That's why I made this tool. (Anyway later I found that the first library can be written in C# but it is a topic for another article - "How to write Terminal Services addin in pure C#" .)

Using the Code

Well the code is just the code ... it's a home-grown parser with some other functionality... So I'll rather write how to use it (and sometimes how it works).

Beginning

What you need to use it:

  • Framework 2.0 SDK
  • Visual Studio 2005 (optional)

First you should download the code (there are two projects ExportDll.exe and ExportDllAttribute.dll) and build it.

Then you should know how to use it... After creating the library project in C# or VB.NET, you need to add dependency to ExportDllAttribute. "Oh no, not another dependency" - you'll say. Easy ... just wait ... This library contains an attribute which tells ExportDll.exe that some function needs to be exported.

How It Works

As I said, ExportDll.exe needs to know which functions need to be exported. So you'll write something like this:

public class SomeClassName
{
    //second parameter of attribute is calling convention,
    //default is StdCall but u can use others fx.:
    [ExportDllAttribute.ExportDll("ExportNameOfFunction",
    System.Runtime.InteropServices.CallingConvention.Cdecl)]
    public static void SomeFunctionName()
    {
        System.Console.WriteLine("I really do nothing");
    }
}

After compiling, you need to use ExportDll tool to export this:

ExportDll.exe full_path_to_yours_dll\yoursdll.dll [/Release|/Debug]

Note: /Release flag is default. What exactly does ExportDll do:

  • Reads DLL as assembly and makes a dictionary of exported function
  • Decompiles DLL
  • Searches and replaces some stuff in IL code (If you want to know what, read the article that I mentioned in the "Background" section.)
  • Deletes ExportDllAttribute dependency

    .assembly extern ExportDllAttribute
    {
      .ver x:x:x:x
    }

    and

    .custom instance void
        [ExportDllAttribute]ExportDllAttribute.ExportDllAttribute ...
  • Compiles modified IL code again

Post-building in Visual Studio 2005

How? It's easy... Just add in Project property named "Post-build event command".

"path_to_tools\ExportDll.exe" "$(TargetPath)" /$(ConfigurationName)

OMG! It's Not Working

Hmm... Yes, forgot to mention about ExportDll.exe.cofig ...

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" 
        type="System.Configuration.ApplicationSettingsGroup, 
        System, Version=2.0.0.0, Culture=neutral, 
        PublicKeyToken=b77a5c561934e089" >
            <section name="ExportDll.Properties.Settings"
        type="System.Configuration.ClientSettingsSection,
        System, Version=2.0.0.0, Culture=neutral,
        PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <applicationSettings>
        <ExportDll.Properties.Settings>
            <setting name="ildasmpath" serializeAs="String">
                <value>C:\Program Files\
                Microsoft Visual Studio 8\SDK\v2.0\Bin\ildasm.exe</value>
            </setting>
            <setting name="ilasmpath" serializeAs="String">
                <value>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ilasm.exe
                </value>
            </setting>
        </ExportDll.Properties.Settings>
    </applicationSettings>
</configuration>

You need to configure path to ilasm and ildasm.

Updates

New version

  • now accept MarshalAsAtrribute
  • new commands in command line support: first had to be TargetPath then you can add:
    /release or /debug - /release id default
    /AnyCPU or /x64 - /AnyCPU is default its for 32/64 bit (for itanium add /PE64 /ITANIUM)
    ... any valid command for ildasm.exe
  • support fo x64
    "path_to_tools\ExportDll.exe" "$(TargetPath)" /$(ConfigurationName) /$(PlatformName)
    if PlatformName == "AnyCPU" then compiles for 32 bit
    if PlatformName == "x64" then compiles for 64 bit
  • now its compiled for runtime 4.0(ExportDll.exe) and 2.0 (ExportDllAttribut.dll) so it should be working for frameworks 2.0 - 4.0
  • it can compile for 2.0 or 4.0 runtime (runtime its not framework - frm 3.0 and 3.5 are using 2.0 runtime)
    it can be change by changing ilasmpath setting so:
    2.0 => C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ilasm.exe
    4.0 => C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe

References

License

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

About the Author

Selvin
Systems / Hardware Administrator
Poland Poland
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCould Not load file or assemblymemberHartarto Junaedi12 May '13 - 16:56 
QuestionGetting Error Building WCF Examplememberchuckmoore5528 Feb '13 - 13:15 
QuestionRe: Export using struct as a parametermembermla15427 Feb '13 - 9:53 
QuestionRe: Export using struct as a parametermembermla15427 Feb '13 - 10:01 
GeneralMy vote of 5memberdhsc4 Dec '12 - 2:57 
GeneralRe: My vote of 5memberSelvin4 Dec '12 - 2:59 
GeneralMy vote of 5memberggxPrince24 Feb '12 - 16:12 
QuestionMantain DLL statemembervss4 Jan '12 - 12:25 
AnswerRe: Mantain DLL statememberSelvin5 Jan '12 - 4:35 
QuestionCompile ErrormemberMember 835485227 Oct '11 - 17:29 
Hi I am getting this error:
 
Kinect Dll Plugin -> C:\Users\HMS\Documents\Kinect(David)\Kinect Working Code\Kinect Dll Plugin\Kinect Dll Plugin\bin\Release\KinectFramework.dll
KinectFramework.il(497) : warning -- Reference to undeclared extern assembly 'ExportDllAttribute'. Attempting autodetect
KinectFramework.il(497) : warning -- Failed to autodetect assembly 'ExportDllAttribute'
Could not open Release.il
 

When I run the tool. Any ideas?
Thanks!
QuestionTarget should be dllmemberMember 835485227 Oct '11 - 15:50 
AnswerRe: Target should be dllmemberMember 835485227 Oct '11 - 17:28 
SuggestionChanging Calling Convention Issuememberheinfrisch15 Sep '11 - 17:59 
QuestionArguments to DLLExportmembercarl looper15 Aug '11 - 17:08 
QuestionHow about c# dll for Pocket PCmemberalfwolf_ss8 Aug '11 - 20:45 
AnswerRe: How about c# dll for Pocket PCmemberSelvin8 Aug '11 - 20:52 
GeneralRe: How about c# dll for Pocket PCmemberalfwolf_ss9 Aug '11 - 17:44 
GeneralRe: How about c# dll for Pocket PCmemberSelvin9 Aug '11 - 21:55 
GeneralAnother Vote o 5memberKeith Lockwood20 Jul '11 - 6:00 
QuestionTrouble passing stringsmemberbkovacic24 Jun '11 - 6:13 
GeneralProblem with ExportDll function in ExportDllAttributememberMember 45233015 Jun '11 - 22:01 
GeneralRe: Problem with ExportDll function in ExportDllAttributememberMember 45233015 Jun '11 - 22:08 
GeneralDeclare someclass where?memberocean_blue417 May '11 - 21:04 
GeneralRe: Declare someclass where?memberSelvin17 May '11 - 21:22 
GeneralRe: Declare someclass where?memberocean_blue417 May '11 - 21:35 
GeneralRe: Declare someclass where?memberSelvin17 May '11 - 21:45 
GeneralMy vote of 5memberjoffreyb11 May '11 - 17:51 
GeneralN0 exported functions...memberDonald Neisler15 Mar '11 - 10:34 
GeneralRe: N0 exported functions...memberSelvin18 Mar '11 - 16:39 
GeneralTAB Key not workingmembervss15 Mar '11 - 6:23 
GeneralRe: TAB Key not workingmemberSelvin18 Mar '11 - 16:34 
GeneralMarshalling Objectmembersaplpete24 Jan '11 - 7:46 
GeneralRe: Marshalling ObjectmemberSelvin24 Jan '11 - 23:18 
GeneralRe: Marshalling Objectmembersaplpete25 Jan '11 - 10:35 
GeneralRe: Marshalling ObjectmemberSelvin25 Jan '11 - 11:34 
GeneralRe: Marshalling Objectmembersaplpete26 Jan '11 - 7:22 
GeneralRe: Marshalling ObjectmemberSelvin26 Jan '11 - 7:27 
GeneralRe: Marshalling ObjectmemberSelvin26 Jan '11 - 7:47 
GeneralRe: Marshalling Object [modified]membersaplpete27 Jan '11 - 7:38 
GeneralRe: Marshalling Objectmembersaplpete13 Feb '11 - 4:59 
GeneralRe: Marshalling Objectmembersaplpete15 Feb '11 - 10:07 
GeneralMy vote of 5memberSAKryukov6 Jan '11 - 9:54 
GeneralRegister for COM interop or RegAsm ProblemmemberMember 25330798 Dec '10 - 0:59 
GeneralRe: Register for COM interop or RegAsm ProblemmemberSelvin8 Dec '10 - 2:09 
GeneralRe: Register for COM interop or RegAsm ProblemmemberMember 25330798 Dec '10 - 12:05 
GeneralRe: Register for COM interop or RegAsm ProblemmemberSelvin9 Dec '10 - 1:06 
GeneralRe: Register for COM interop or RegAsm ProblemmemberMember 253307915 Dec '10 - 19:42 
GeneralRe: Register for COM interop or RegAsm ProblemmemberMember 253307916 Dec '10 - 22:57 
GeneralRe: Register for COM interop or RegAsm ProblemmemberSelvin21 Dec '10 - 0:18 
Generalstdcall decorationmembersquidward19 Oct '10 - 23:04 

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 22 Nov 2006
Article Copyright 2006 by Selvin
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid