For example, take the Windows GetPrivateProfileSectionNames
API. This function exists in the Win32 API purely for compatibility with 16-bit Windows, so it wasn't a top compatibility priority for the .NET Framework designers. The weird thing about GetPrivateProfileSectionNames
is that it returns a flattened array of strings in a single buffer. Each string is terminated by a null character, and the final string is terminated by two nulls in a row.
If you try to import that into .NET using a StringBuffer
, you'll get the first string only. If you try to muck with the marshalling, all you're likely to do is to wind up with a corrupted form of the first string.
|The weird thing about GetPrivateProfileSectionNames is that it returns a flattened array of strings in a single buffer.|
The solution to this dilemma (and a big tip o' the hat to Russell Jones for figuring this out) is to return the strings into a byte array, call GetString
from the System.Text
namespace to convert that into a single string containing with internal nulls, and finally use the String
method to separate the individual name strings.
As you'll see in the code that follows, we specified the ANSI form of the API function, so that it would work both on the Windows 9x and NT families.
// DWORD GetPrivateProfileSectionNames(
// LPTSTR lpszReturnBuffer, // return buffer
// DWORD nSize, // size of return buffer
// LPCTSTR lpFileName
// initialization file name
static extern uint
static void Main(string args)
byte buff=new byte;
String s =
foreach(String name in names)
Essentially the same method will also work in Visual Basic .NET. When you run the downloadable code for this article
, you'll get a list of the section names in the current machine's win.ini
file. The exact list depends on what's been installed on the machine.
In the next part of this article
, I'll discuss how to use the MarshalAs and the StructLayout options to control precisely how the runtime passes data to and from unmanaged code.