从C#程序中调用非受管DLLs的方法
本文实例讲述了从C#程序中调用非受管DLLs的方法。分享给大家供大家参考。具体方法如下:
前言:
从所周知,.NET已经渐渐成为一种技术时尚,那么C#很自然也成为一种编程时尚。如何利用浩如烟海的Win32API以及以前所编写的Win32代码已经成为越来越多的C#程序员所关注的问题。本文将介绍如何从C#代码中调用非受管DLLs。如果某个函数是一个带有串类型(char*)输出参数的Win32API或者是DLL输出函数,那么从C#中如何调用它呢?对于输入参数的情形问题到不大,但如何获取从参数中返回的串呢?此外,如何调用有结构(struct)和回调(callback)作为参数的函数,如GetWindowsRect和EnumWindows?那我们又如何将参数从C++和MFC中转换成C#所要的类型呢?下面就让我们来一一解决这些问题。
微软.NET的一个最主要的优势是它提供一个语言无关的开发系统。我们可以用VisualBasic、C++、C#等等语言来编写类,然后在其它语言中使用,我们甚至可以用不同的语言来派生类。但是如何调用以前开发的非受管DLL呢?方法是必须将.NET对象转化成结构、char*以及C语言的指针。用行话说就是参数必须被列集(marshal)。说到列集,用一两句话也说不清楚。所幸的是实现列集并不要我们知道太多的东西。
为了从C#中调用DLL函数,首先必须要有一个声明,就象长期以来使用VisualBasic的程序员所做的那样,只不过在C#中使用的是DllImport关键字:
usingSystem.Runtime.InteropServices;//DllImport所在的名字空间 publicclassWin32{ [DllImport("User32.Dll")] publicstaticexternvoidSetWindowText(inth,Strings); }
在C#中,DllImport关键字作用是告诉编译器入口点在哪里,并将打包函数捆绑在一个类中。我们可以为这类取任何名字,这里不妨将类名取为Win32。我们甚至可以将这个类放到一个名字空间中,就象下面的代码这样:
Win32API.cs源代码
//Win32API:此为名字空间,打包所选的Win32API函数 //编译方法: // csc/t:library/out:Win32API.dllWin32API.cs // usingSystem; usingSystem.Drawing; usingSystem.Text; usingSystem.Runtime.InteropServices;
///////////////////////////////////////////////////////////////// //包装Win32API函数的名字空间。想用哪个Win32API,往里添加即可。 // namespaceWin32API{ [StructLayout(LayoutKind.Sequential)] publicstructPOINT{ publicPOINT(intxx,intyy){x=xx;y=yy;} publicintx; publicinty; publicoverridestringToString(){ Strings=String.Format("({0},{1})",x,y); returns; } }
[StructLayout(LayoutKind.Sequential)] publicstructSIZE{ publicSIZE(intcxx,intcyy){cx=cxx;cy=cyy;} publicintcx; publicintcy; publicoverridestringToString(){ Strings=String.Format("({0},{1})",cx,cy); returns; } }
[StructLayout(LayoutKind.Sequential)] publicstructRECT{ publicintleft; publicinttop; publicintright; publicintbottom; publicintWidth() {returnright-left;} publicintHeight() {returnbottom-top;} publicPOINTTopLeft() {returnnewPOINT(left,top);} publicSIZE Size() {returnnewSIZE(Width(),Height());} publicoverridestringToString(){ Strings=String.Format("{0}x{1}",TopLeft(),Size()); returns; } }
publicclassWin32{ [DllImport("user32.dll")] publicstaticexternboolIsWindowVisible(inthwnd);
[DllImport("user32.dll")] publicstaticexternintGetWindowText(inthwnd, StringBuilderbuf,intnMaxCount);
[DllImport("user32.dll")] publicstaticexternintGetClassName(inthwnd, [MarshalAs(UnmanagedType.LPStr)]StringBuilderbuf, intnMaxCount);
[DllImport("user32.dll")] publicstaticexternintGetWindowRect(inthwnd,refRECTrc);
[DllImport("user32.dll")] //注意,运行时知道如何列集一个矩形 publicstaticexternintGetWindowRect(inthwnd,refRectanglerc); } }