Jim Lahman's Blog

Fortitude|Endurance|Faith|Teamwork

  Home  |   Contact  |   Syndication    |   Login
  30 Posts | 0 Stories | 18 Comments | 0 Trackbacks

News

Archives

Links

Social

When I was working in VC++, it was relatively easy to include a win32 API function.  All we did was include the header file and then made a call to a function like so:
 
        #include <Mailbox.h>
 
                CMailbox::MbxStatus CMailbox::iCreateMbx() {
        MbxStatus iStatus = mbxSuccess;

        switch ( m_iType ) {
        case mbxReceiver:
        case mbxBoth:
                // for receive type mailboxes we need to create a
                // space for the reception of data
                /* if ( m_hRecvMbx ) CloseHandle( m_hRecvMbx ); */
                m_hRecvMbx = ::CreateMailslot(
                        m_strInName,
                        0,
                        MAILSLOT_WAIT_FOREVER,
                        &( SECURITY_ATTRIBUTES )m_saInfo // previously was NULL
                );

                // if the mailslot already exists, return error
                if ( m_hRecvMbx == INVALID_HANDLE_VALUE ) {
                        m_hRecvMbx = NULL;
                        iStatus = mbxCreateFailure;
                }
                /* if ( m_iType == mbxReceiver ) */ break;

        case mbxSender:
                // for send type mailboxes we need to obtain a
                // target to send to
                iStatus = iSetReceiver( m_strOutName );
                break;
        }

        return iStatus;
            }
 
 
But, now, we have to use interop services because the DLL functions are considered to be in unmanaged code, which does not execute under the control of the CLR.
 
The list of DLL functions are listed in the MSDN in the Platform SDK as System Services.
 
Use DLLImport to specify  an entry point into the DLL for the win32 function that is to be called.  The DLLImport Attribute has four fields: EntryPoint, CharSet, CallingConvention, SetLastError.  From the MSDN library, these are defined as such:
 

DllImportAttribute field

Description

EntryPoint

Specifies the DLL entry point to be called. The default entry point name is the name of the managed method.

CharSet

Controls the name mangling and the way that String parameters should be marshaled. The .NET Compact Framework only supports CharSet..::.Unicode and CharSet..::.Auto. CharSet..::.Auto equates to CharSet..::.Unicode on Windows CE. The default marshaling on the .NET Compact Framework is CharSet..::.Unicode, unlike the .NET Framework that defaults to CharSet..::.Ansi.

Because the .NET Compact Framework does not support the DllImportAttribute..::.ExactSpelling field, the common language runtime automatically searches for an entry point according to the values specified by CharSet.

CallingConvention

Specifies the calling-convention values used in passing method arguments. The default is CallingConvention..::.Winapi, which corresponds to __cdecl on the Windows CE platform.

SetLastError

Enables the caller to use the GetLastWin32Error method to determine whether an error occurred while executing the platform invoke method. In Visual Basic 2005, the default is true; in C#, the default is false.

 
Here's an example of using the DLLImport attribute:
 
        [DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern IntPtr CreateFile (
            String lpFileName, int dwDesiredAccess, int dwShareMode,
            ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition,
            int dwFlagsAndAttributes, IntPtr hTemplateFile );
 
I want to make a few notes about the way a win32 function is defined:
 
   1. Use the extern keywprd as it defines a function as external, meaning it is implemented outside the C# code.
   2. Verify that the function definition matches its signature found in the DLL
   3. Some functions return a handle or pointer.  In this case use the IntPtr type since it represents a pointer/handle in the .Net world.
   4. On a personal note, I like putting these definitions in its own class.
 
Once a win32 function is defined, we use it as follows:
 
hFile = Win32Api.CreateFile (  
                fileName,                       // Filename
                desiredAccess,                  // Open Read/Write
                desiredShare,                   // Share Reading
                ref security_attributes,        // NULL Security new 15-May-2007
                OPEN_ALWAYS,                    // Creation attrib
                desiredAttrib,                  // File Attributes
                IntPtr.Zero  );                 // NULL  no template
 
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted on Tuesday, April 07, 2009 9:51 AM

Feedback

# re: Using win32 API in C# 12/16/2009 11:47 PM Ranjeesh
I have always been a fan of using APIs. This makes it look very simple.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: