Click here to Skip to main content
15,884,099 members
Articles / Programming Languages / C#
Article

Loop holes around PInvoke

Rate me:
Please Sign up or sign in to vote.
3.59/5 (53 votes)
4 Mar 20043 min read 112.4K   30   22
Features some tricks related to File IO.

Introduction

In working with PInvoke, I found it utterly tedious having to write those structures as arguments to pass into the function calls. Particularly, since I myself am not a Win32 developer. I decided to start an article focused on some shortcuts (good or bad) one can use to speed up the whole process. Here are just some things to make the job a little easier (if you didn't already know). This article is intended to serve as a journal of findings and as such will remain a living document. If there are any quick tricks you know as a reader, please inform me so I can update it. :-)

Opening files/devices/etc

In Win32, the CreateFile function is used as a general access method to open files, named pipes, directories, communication resources, physical disks, volumes, the console buffer, tape drives, or mail slots. Here is the basic signature for the function:

HANDLE CreateFile(
  LPCTSTR filename,
  DWORD fileaccess,
  DWORD fileshare,
  LPSECURITY_ATTRIBUTES securityattributes,
  DWORD creationdisposition,
  DWORD flags,
  HANDLE template);

Most of the samples I have seen take the approach of creating constants to represent the various values associated with the parameters: fileaccess, fileshare, and creationdisposition. You can however use the FileAcces enum to represent fileaccess, the FileMode enum to represent creation-disposition and the FileShare enum to represent fileshare. You would simply have to manually marshal the enums as integers. Since enums in .NET represent integer type constants, this should not be a problem. Here is how the declaration of CreateFile would look:

C#
[DllImport("Kernel32.dll")]

static extern IntPtr CreateFile(
                string filename,
                [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
                [MarshalAs(UnmanagedType.U4)]FileShare fileshare,
                int securityattributes,
                [MarshalAs(UnmanagedType.U4)]FileMode creationdisposition,
                int flags,
                IntPtr template);

I use int for securityattributes to illustrate that (if you are not planning to use it, you can simple map it as an int and pass 0 rather than create the entire structure just to pass it in).

With the above function declared, you can call CreateFile from your code much easier:

C#
IntPtr ptr= CreateFile("text.txt",FileAccess.ReadWrite,
    FileShare.ReadWrite,0,FileMode.Create,0, IntPtr.Zero);

The above code will return a handle that can be used to access the object.

If you specified "COM1" as the filename above (you would have to change some of the parameters), you would get back a handle to the COM port 1. Trying to do this with the File factory provided by .NET as follows:

C#
FileStream fs = File.Create("COM1");

will not work. CreateFile however does not return a FileStream; rather you get back a Handle which you must the pass in subsequent calls to other IO functions like CreateFileMapping. In the case of serial communication, the standard practice is to use the read and write Win32 functions to read from and write to the port. Here is the definition for WriteFile.

BOOL WriteFile(
  HANDLE hfile,
  LPCVOID pointertobuffer,
  DWORD numberofbytestowrte,
  LPDWORD numberofbyteswritten,
  LPOVERLAPPED useoverlappedio
);

Fortunately, you do not have to do this. Although .NET does not allow you to directly open devices, (the example I showed above), it does let you create filestreams from Windows handles (yeah!), so you could access the stream associated with the device like this:

C#
IntPtr ptr= CreateFile("COM1",
FileAccess.ReadWrite,
FileShare.ReadWrite,
0,
FileMode.Create,
0,
IntPtr.Zero //pointed out by Parrys
);
FileStream fs = new FileStream(ptr,FileAccess.ReadWrite);

Because the File class allows you to get an instance to a FileStream from the handle of a file, you can open a file using standard Win32 mechanism, use its handle to create a FileStream, and write to it using all the standard .NET mechanisms. It's not much to write home about when you're just working with files, but with some imagination you can achieve the equivalent of:

C#
FileStream fs = File.Open("//./device",FileMode.open);

Something that is not yet implemented in .NET. Using this in tandem with DeviceIOControl can bring .NET pretty close to the AssemblyZone.

Multimedia

For quick access to cross platform multimedia functionality such as playing all waveform audio, capturing video & audio, etc., use the multimedia library winmm.dll. It gives very low level access to everything without having to redistribute DirectX. In fact, you can you the mciSendString() function and just send text based messages directly to the multimedia device drivers. Please see the article below for a more detailed description of this:

Using MCI to control multimedia.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
Hi I'm Edward Moemeka,
For more interesting articles about stuff check out my blog at http://moemeka.blogspot.com
To correspond, email me at edward.moemeka@synertry.com
To support my company, thus help me feed my family, check out our awesome online preview at www.synertry.com. Remember, its in alpha Wink | ;-)

Comments and Discussions

 
GeneralProblem with P/Invoke Pin
t4ure4n16-Apr-06 7:06
t4ure4n16-Apr-06 7:06 
GeneralRe: Problem with P/Invoke Pin
suzalinda4-Feb-10 8:03
suzalinda4-Feb-10 8:03 
GeneralWaveform audio interface component for .NET Pin
AdamSlosarski2-Nov-05 1:50
AdamSlosarski2-Nov-05 1:50 
GeneralThanks it was great help Pin
rakesh_nits28-Aug-05 23:35
rakesh_nits28-Aug-05 23:35 
QuestionExample of DeviceIoControl? Pin
BillyBox6-Jul-04 15:21
BillyBox6-Jul-04 15:21 
GeneralChanging strings Pin
BrcKcc15-Apr-04 5:50
BrcKcc15-Apr-04 5:50 
GeneralRe: Changing strings Pin
suzalinda4-Feb-10 8:18
suzalinda4-Feb-10 8:18 
GeneralThank you!! Pin
ajcg7-Apr-04 23:34
ajcg7-Apr-04 23:34 
GeneralRe: Thank you!! Pin
Edward Moemeka8-Apr-04 5:35
Edward Moemeka8-Apr-04 5:35 
GeneralFileAccess, etc. Pin
Rudy Velthuis7-Mar-04 4:29
Rudy Velthuis7-Mar-04 4:29 
GeneralIntPtr Pin
Parrys18-Feb-04 0:06
Parrys18-Feb-04 0:06 
GeneralAutomatation of wrappers with WinBase.h Pin
YosefDov16-Feb-04 19:59
YosefDov16-Feb-04 19:59 
GeneralMaybe a real way to go around P/Invoke Pin
User 35433213-Feb-04 2:58
User 35433213-Feb-04 2:58 
GeneralInteresting article Pin
Nish Nishant12-Feb-04 16:28
sitebuilderNish Nishant12-Feb-04 16:28 
GeneralI'm not sure... Pin
Marc Clifton12-Feb-04 15:59
mvaMarc Clifton12-Feb-04 15:59 
GeneralRe: I'm not sure... Pin
Nish Nishant12-Feb-04 16:30
sitebuilderNish Nishant12-Feb-04 16:30 
Marc Clifton wrote:
why this is getting such a low rating

Hey Marc

I think the average article-viewer expects screen shots, downloadable code and a long article every single time.

So he comes here and sees a short article, no fancy JPGs, no downloads and gives it a 1 Sigh | :sigh:

I gave it a 5 to boost the rating a little.

Marc Clifton wrote:
I think you present some innovative and alternative solutions to some rather frustrating things about .NET.

Yup, that's what I thought too. The article idea is quite original and innovative!

Nish


Extending MFC Applications with the .NET Framework [NW]
Summer Love and Some more Cricket [NW] (My first novel)
Shog's review of SLASMC [NW]
Nish is now the first and only CPian (as of now) to reach 16,000 forum posts on CodeProject.
GeneralRe: I'm not sure... Pin
David M. Kean12-Feb-04 21:20
David M. Kean12-Feb-04 21:20 
GeneralRe: I'm not sure... Pin
Nish Nishant12-Feb-04 22:08
sitebuilderNish Nishant12-Feb-04 22:08 
GeneralRe: I'm not sure... Pin
Keith Farmer13-Feb-04 9:14
Keith Farmer13-Feb-04 9:14 
GeneralRe: I'm not sure... Pin
Rocky Moore13-Feb-04 15:13
Rocky Moore13-Feb-04 15:13 
GeneralI hope... Pin
leppie12-Feb-04 10:22
leppie12-Feb-04 10:22 
GeneralRe: I hope... Pin
Edward Moemeka12-Feb-04 11:01
Edward Moemeka12-Feb-04 11:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.