mahua22
mahua22

Reputation: 151

C++ LPSTR To C# String .Net Wrapper

I have an API that takes three parameters

BOOL GetServerName (int index, LPSTR Buffer, int BufSize); 

how can i use this method in C#

What is the equivalence of LPSTR ?

Upvotes: 3

Views: 7506

Answers (1)

xanatos
xanatos

Reputation: 111860

[DllImport("YourDll.dll", CharSet = CharSet.Ansi)]
//[return: MarshalAs(UnmanagedType.Bool)] // This line is optional, and it's implicit
static extern bool GetServerName(int index, StringBuilder buffer, int bufSize);

To use it:

int bufSize = 100;
StringBuilder buffer = new StringBuilder(bufSize);
bool result = GerServerName(0, buffer, bufSize);

if (result) 
{
    string buffer2 = buffer.ToString();
}

Technically your question was "what is equivalent to LPSTR"... The response is: string or StringBuilder if you are passing the string to the method, StringBuilder if the method is passing the string to you. Another alternative is using a byte[] and doing the Encoding/Decoding yourself, like:

[DllImport("YourDll.dll", CharSet = CharSet.Ansi)]
//[return: MarshalAs(UnmanagedType.Bool)] // This line is optional, and it's implicit
static extern bool GetServerName(int index, byte[] buffer, int bufSize);

and

int bufSize = 100;
byte[] buffer = new byte[bufSize];
bool result = GerServerName(0, buffer, bufSize);

if (result) 
{
    string buffer2 = Encoding.Default.GetString(buffer, 0, Array.IndexOf(buffer, (byte)0));
}

(C string are null terminated. We find the first \0 with Array.IndexOf(buffer, (byte)0) and we convert the characters up to the null to a string with Encoding.Default.GetString()).

Some comments...

  1. I hope you have the maximum length of buffer (like a constant), because normally these methods are written as returning in some way the length of the string.
  2. If you have an Unicode version of the method (perhaps GetServerNameW), you should use it. It's better to use Unicode methods if present, so non-Ansi characters aren't lost.

As a sidenote, when you use DllImport, you should check if you are using the correct calling convention. For Windows API you don't need to do anything, but depending on how the method has been defined in the header file, you could need to add CallingConvention = CallingConvention.something). Often (but now always) the .NET runtime will throw an exception on wrong calling convention, or the method won't work and will return strange things or will crash. This is because the calling convention tells the .NET how the parameters must be passed to the method (where, how, and who has to free the stack technically). Some examples of calling conventions in header files are cdecl, stdcall, fastcall, thiscall, pascal (equivalent to stdcall), WINAPI, APIENTRY (equivalent to WINAPI), CALLBACK (equivalent to WINAPI) and all of these words with _ or __ prepended or in all upper case. The Microsoft VC++ normally uses the cdecl calling convention for C methods and the thiscall for C++ methods. You can control it through some arguments.

Upvotes: 8

Related Questions