日期:2011-05-30 浏览次数:20587 次
这是三篇网上收集的技术文章的合集,分别讲解了如何创建Win32 DLL,然后如何在C#里面调用这个DLL的教程。
首先是创建Win32 DLL的文章。讲解这个的文章到处都有,这里给出一篇我看过的:http://www.flipcode.com/articles/article_creatingdlls.shtml。Win32 DLL的创建其实在Visual Studio里面已经给出了比较好的模板,只是需要注意的,有些XXX_API宏并没有把extern "C"加进去,这样会造成在C#里面找不到这个函数的错误。所以,请记住,一定要把函数定义extern "C"。
第二篇文章来之于http://edu.100down.com/it/program/Csharp/105256797.html,下面是转贴内容:
平台调用服务 (PInvoke) 允许托管代码调用在 DLL 中实现的非托管函数。
本教程说明使用什么方法才能从 C# 调用非托管 DLL 函数。该教程所讨论的属性允许您调用这些函数并使数据类型得到正确封送。
C# 代码有以下两种可以直接调用非托管代码的方法:
对于这两种技术,都必须向 C# 编译器提供非托管函数的声明,并且还可能需要向 C# 编译器提供如何封送与非托管代码之间传递的参数和返回值的说明。
该教程由下列主题组成:
该教程包括下列示例:
若要声明一个方法使其具有来自 DLL 导出的实现,请执行下列操作:
本示例显示如何使用 DllImport 属性通过调用 msvcrt.dll
中的 puts
输出消息。
// PInvokeTest.csusing System;using System.Runtime.InteropServices;class PlatformInvokeTest{ [DllImport("msvcrt.dll")] public static extern int puts(string c); [DllImport("msvcrt.dll")] internal static extern int _flushall(); public static void Main() { puts("Test"); _flushall(); }}
Test
前面的示例显示了声明在非托管 DLL 中实现的 C# 方法的最低要求。PlatformInvokeTest.puts
方法用 static 和 extern 修饰符声明并且具有 DllImport 属性,该属性使用默认名称 puts
通知编译器此实现来自 msvcrt.dll
。若要对 C# 方法使用不同的名称(如 putstring
),则必须在 DllImport 属性中使用 EntryPoint 选项,如下所示:
[DllImport("msvcrt.dll", EntryPoint="puts")]
有关 DllImport 属性的语法的更多信息,请参见 DllImportAttribute 类。
当从 C# 代码中调用非托管函数时,公共语言运行库必须封送参数和返回值。
对于每个 .NET Framework 类型均有一个默认非托管类型,公共语言运行库将使用此非托管类型在托管到非托管的函数调用中封送数据。例如,C# 字符串值的默认封送处理是封送为 LPTSTR(指向 TCHAR 字符缓冲区的指针)类型。可以在非托管函数的 C# 声明中使用 MarshalAs 属性重写默认封送处理。
本示例使用 DllImport 属性输出一个字符串。它还显示如何通过使用 MarshalAs 属性重写函数参数的默认封送处理。
// Marshal.csusing System;using System.Runtime.InteropServices;class PlatformInvokeTest{ [DllImport("msvcrt.dll")] public static extern int puts( [MarshalAs(UnmanagedType.LPStr)] string m); [DllImport("msvcrt.dll")] internal static extern int _flushall(); public static void Main() { puts("Hello World!"); _flushall(); }}
运行此示例时,字符串
Hello World!
将显示在控制台上。
在前面的示例中,puts
函数的参数的默认封送处理已从默认值 LPTSTR 重写为 LPSTR。
MarshalAs 属性可以放置在方法参数、方法返回值以及结构和类的字段上。若要设置方法返回值的封送处理,请将 MarshalAs 属性与返回属性位置重写一起放置在方法上的属性块中。例如,若要显式设置 puts
方法返回值的封送处理:
...[DllImport("msvcrt.dll")] [return : MarshalAs(UnmanagedType.I