随笔 - 89, 评论 - 163, 引用 - 33

导航

关于

标签

每月存档

最新留言

广告

 
[原文作者]Jared Parsons
[原文链接]Making PInvoke Easy
 
     我非常兴奋的宣布我们最近发布了一个工具,这个工具对我们在托管代码中使用PInvoke非常有用。这个工具的名 字是PInvoke Interop Assistant”,“PInvoke Interop Assistant”作为PInvokeReverse PInvoke场景的一部分已经被包含在MSDN文章中。
 
    下面的链接是文章和工具
·         ToolCLRInsideOut2008_01.exe
 
 
   开发这个工具背后的动力是写PInvoke是一个艰难并且乏味的任务。有很多规则必须遵守,很多异常必须要考虑到。所有在简单的数据结构之外的东西必须专心的做,C当中微妙的语义会很大程度上改变所需的签名。不正确的翻译经常会导致不明确的异常或者崩溃。
 
   简而言之,这个差事没有什么乐趣。
 
   这个工具可以用很多方式让PInvoke产生更简单的进程。目标是为structunionsenumsconstantsfunctionstypedefs等等产生尽可能简单的托管代码。这些代码可以在VBC# 中生成。
 
   工具中三个选项卡的GUI版本:
1. Siglmp Search: 搜索常用的方法,然后翻译成托管代码。
2. Siglmp Translate Snippet:直接翻译C代码到托管的PInvoke签名中去。
3. SigExp:转换托管的二进制代码到C++ Reverse PInvoke 场景中。
 
   前面两个是我的工作部分,也是代表PInvoke的场景。第三个是Ladi Prosek写的,这部分另外一篇文章会讲到。我们选择SiglmpSigExp这两个名字来反映工具tblimp/tlbexp,因为他们有差不多的方法。
 
    直接翻译C代码到PInvoke签名中
 
    在PInvoke中大部分的冒险是,开发者想用托管代码中的一小部分C代码。典型的是一两个有C结构体的方法。以前,所有这样的情况需要从一开始就翻译进托管代码中。用这个工具,你只需要把代码粘贴到这个工具里面,然后它就会生成相应的签名。
 
    例如假设你想翻译下面的C代码到VB
 
struct S1
{
 int a;
 char[10] b;
};
 
float CalculateData(S1* p);
 
    把工具打开,转换到“Siglmp Translate Snippet”选项。粘贴这些代码,然后按Generate按钮。
    你也可以按“Auto Generate“,然后看着你键入的代码更新。
 
    这种翻译不限制于内置的 C类型。它还可以解决大多数通用的windows类型,例如HANDLEDWORD所有的这些到复杂的结构体例如WIN32_FIND_DATA
 
    搜索常用的方法
 
    通常开发者想在托管代码中用他们熟悉的C函数。这也是一个乏味的任务,因为如果这个签名现在还不是可以得到的,那么你就要从头编码。如果你不知道到哪个头文件里面去查的话,加一个常量是不易处理的。
    这个工具提供了一个有常用的方法,结构体,常量等的数据库。基本上windows.h包含了所有的东西。转换到Siglmp的搜索键,键入你想搜索的名字,然后敲generate。例如你想看WM_PAINT的值。   
     另外,工具的这部分还会做附属的分析。例如,选择一个有C结构的方法,它会自动生成方法的结构。例如,你选FindFirstFile,它会知道这个方法依赖于WIN32_FIND_DATA这个结构。另外,它还会注意到WIN32_FIND_DATA依赖于FILETIME然后会生成这两个到方法里面去。
 
<System.Runtime.InteropServices.StructLayoutAttribute( _
    System.Runtime.InteropServices.LayoutKind.Sequential, _
    CharSet:=System.Runtime.InteropServices.CharSet.[Unicode])> _
Public Structure WIN32_FIND_DATAW
    '''DWORD->unsigned int
    Public dwFileAttributes As UInteger
    '''FILETIME->_FILETIME
    Public ftCreationTime As FILETIME
    '''FILETIME->_FILETIME
    Public ftLastAccessTime As FILETIME
    '''FILETIME->_FILETIME
    Public ftLastWriteTime As FILETIME
    '''DWORD->unsigned int
    Public nFileSizeHigh As UInteger
    '''DWORD->unsigned int
    Public nFileSizeLow As UInteger
    '''DWORD->unsigned int
    Public dwReserved0 As UInteger
    '''DWORD->unsigned int
    Public dwReserved1 As UInteger
    '''WCHAR[260]
    <System.Runtime.InteropServices.MarshalAsAttribute( _
        System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=260)> _
    Public cFileName As String
    '''WCHAR[14]
    <System.Runtime.InteropServices.MarshalAsAttribute( _
        System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=14)> _
    Public cAlternateFileName As String
End Structure
 
<System.Runtime.InteropServices.StructLayoutAttribute( _
    System.Runtime.InteropServices.LayoutKind.Sequential)> _
Public Structure FILETIME
    '''DWORD->unsigned int
    Public dwLowDateTime As UInteger
    '''DWORD->unsigned int
    Public dwHighDateTime As UInteger
End Structure
 
Partial Public Class NativeMethods
    '''Return Type: HANDLE->void*
    '''lpFileName: LPCWSTR->WCHAR*
    '''lpFindFileData: LPWIN32_FIND_DATAW->_WIN32_FIND_DATAW*
    <System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint:="FindFirstFileW")> _
    Public Shared Function FindFirstFileW( _
        <System.Runtime.InteropServices.InAttribute(), _
            System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)> _
            ByVal lpFileName As String, _
        <System.Runtime.InteropServices.OutAttribute()> _
        ByRef lpFindFileData As WIN32_FIND_DATAW) As System.IntPtr
    End Function
End Class
 
    翻译大量的代码
 
   小的翻译器适合翻译小的代码段。如果你想要翻译大量的代码,像彼此依赖的头文件的话,小的翻译器就不会工作得很好了。你应该用这个工具的命令行的版本来翻译大量的代码。sigimp.exe。它是被设计用来进行很多头文件的翻译工作,然后产生大量的输出。
    结语
   以前这个工具就像是我项目的宠物。我十分的兴奋,现在客户可以利用它的优点,我也期待你们给我回馈。稍后,我会帖更多关于这个工具是怎么工作的文章。

打印 | 张贴于 2008-10-28 14:23:20 | Tag:VB Team Blog  Did you know?

留言反馈

#vb 编辑
vb
2008-10-29 22:27:14 | [匿名:]
#Make PInvoke Easy 编辑
Make PInvoke Easy
2008-10-29 22:09:32 | [匿名:]
#Make PInvoke Easy 编辑
Make PInvoke Easy
2008-10-29 22:03:48 | [匿名:]
博客主人设置本博客不允许匿名用户发表言论,请登录后再试

Powered by: Joycode.MVC引擎 0.5.2.0