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
{
[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 ...
="1.0"="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
References