Introduction
This short article shows how to use an exported function from the Microsoft Visual C Run-Time Library wich is almost available on any Windows System starting Windows 95
to the latest Windows 8 to reverse a string in C# within a single line of code.
Background
At times we need to reverese a string in .NET for particular reasons. In general developers code their own functions and classes holding
some sort of class/function pair to accomplish this task, unless there is no ready to use code or external library/assembly available. But the implementation itself
can heavily differ in code quality, speed and size, depending on the developers skills and generated code by the compiler. Keep in your mind, that there are many
more compilers beside the broadly used Microsoft compilers, who can generate IL code and they can differ in optimization and other variables which finally can affect
the applications performance. By using the Microsoft Visual C Run-Time Library functions _strrev()
and/or _wcsrev()
we can quickly reverse a string within a single line of code. These functions can easily be imported and used by a .NET project using the .NET Framework's Interop techniques.
CodeProject has a lot of great articles on the Interop topic, so there is no need to explain what .NET Interop in detail is. By using these two Microsoft supplied functions,
there are some major advantages over external third-party libraries:
- The Microsoft Visual C Run-Time Library is available without exception on any Windows
system starting from Windows 95 to the latest Windows 8, covering the 32- and 64 bit variants. The library itself is de-facto an integral part of the Windows system
and many Windows applications itself depend on its existence to work properly.
- The functions are very well documented and very stable, so they can be safely used in any project without exceptions. Beside the fact that there are different
version available and possibly installed on a system, the input and output data is ALWAYS the same on any library version.
- The library code is maintained by Microsoft and any bugfixes will be available on any Windows systems with new or update releases of the Microsoft Visual C Run-Time Library.
- The code runs pretty fast. Fast means here that the implementation code, the code inside the library, is written in plain C and the only thing to marshal between
the library and the managed application is the string (in fact the string pointer) itself. This can make the reversing operation on even large strings very fast.
Using the code
Using the code is pretty straightforward and the C# signatures can easily be imported to any .NET language like e.g. VB.NET by simply translating them into
their language counterparts. The project files hold a simple C# Visual Studio 2008 file format Forms expample project that shows you a simple application with
basic commented code on how to use these two functions. Lets have a look at the code now:
The very first thing we have to do is to import the System.Runtime.InteropServices
namespace into our project in order to be able to use the Interop
mechanism and use the two functions in our project:
using System.Runtime.InteropServices;
Now we can declare our import functions signatures inside a class in our project. They have to look like this:
[DllImport("msvcrt.dll",
CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string _wcsrev(
[MarshalAs(UnmanagedType.LPWStr)]
[In] string str);
[DllImport("msvcrt.dll",
CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string _strrev(
[MarshalAs(UnmanagedType.LPStr)]
[In] string str);
That's it! Now they can be used like any C# function within your code: Here is a short example to show you how:
public partial class Form1 : Form
{
[DllImport("msvcrt.dll",
CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string _wcsrev(
[MarshalAs(UnmanagedType.LPWStr)]
[In] string str);
[DllImport("msvcrt.dll",
CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string _strrev(
[MarshalAs(UnmanagedType.LPStr)]
[In] string str);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(this.textBox1.Text.Trim()) == true)
{
MessageBox.Show("The original string cant be empty. Please set the original text first!",
this.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return;
}
try
{
this.textBox2.Text = _wcsrev(textBox1.Text);
}
catch (Exception err)
{
MessageBox.Show("Error reversing string: " + err.Message,
this.Text,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
Important to know
Please make sure that you pass in a valid string as the functions parameter and not a null
.
Passing in something like ""
or a string.Empty
(both are the same at runtime) is perfectly fine, but passing in a null
as parameter
will definitely lead to a System.AccessViolationException
kind of exception and crash your application if you dont handle the exception inside a try/catch
block.
History
- 03/01/13 - Initial release
- 04/01/13 - Changed topic text to make it more fit the approach technique
External links
Original documentation for _strrev
, _wcsrev
, _mbsrev
,
_mbsrev_l
:
http://msdn.microsoft.com/en-us/library/9hby7w40%28v=vs.80%29.aspx.