以下是我在调用时用的转换,你可以参考一下:
DWORD 用int 
WORD 用Int16
指针用 out(要先声明) 或ref(要先初始化)
string 用string
数构或类时,用StructLayout声明结构处理
句柄用 IntPtr

解决方案 »

  1.   

    下面是几个系统消息对应的值,转换成INT就可以了,更多的系统消息值,我也不记得了,查看有关资料吧
    WM_MOUSEMOVE = $0200; 
    WM_LBUTTONDOWN = $0201; 
    WM_LBUTTONUP = $0202; 
    WM_LBUTTONDBLCLK = $0203;
    WM_RBUTTONDOWN = $0204;
    WM_RBUTTONUP = $0205;
    WM_RBUTTONDBLCLK = $0206; 
    WM_MBUTTONDOWN = $0207; 
    WM_MBUTTONUP = $0208; 
    WM_MBUTTONDBLCLK = $0209; 
    WM_MOUSEWHEEL = $020A;
    WM_VKEYTOITEM = $002E;
      

  2.   

    void *    intptr
    dword     Uint32
    float     single
    double    double
    int       int32
    char*     string
      

  3.   

    HANDLE  System.IntPtr
    BYTE  byte 
    SHORT  int 
    WORD  uint 
    INT  int 
    UINT  uint 
    LONG  int
    BOOL  int
    DWORD  uint 
    ULONG  uint
    CHAR  char 
    LPSTR  string或 System.StringBuilder 用 ANSI 修饰。 
    LPCSTR  string或 System.StringBuilder 用 ANSI 修饰。 
    LPWSTR  string或 System.StringBuilder 用 Unicode 修饰。 
    LPCWSTR           string或 System.StringBuilder 用 Unicode 修饰。 
    FLOAT  single
    DOUBLE            double
      

  4.   

    推荐一个网站:http://www.webtropy.com/articles/art9-2.asp?lib=user32.dll
    一楼就讲得差不多!
      

  5.   

    这个列表真的不好写,随时遇到新问题才会想到。
    我试着给你写一点:
    HANDLE     System.IntPtr
    DWORD      int   // 好像API调用里就这一种传值的简单类型,反正值传的全是32位,int 搞定
    enum       int   // 也可以自定义枚举类型
    LPDWORD    ref int
    LPCTSTR    [MarshalAs(UnmanagedType.LPTStr)] string //字符串常量
    LPTSTR     [MarshalAs(UnmanagedType.LPTStr)] StringBuiler // 字符串缓冲区
    LPstruct   ref struct // struct 的 Layout 一定要设好,尤其是中间有字符串的情况
    BYTE *     [MarshalAs(UnmanagedType.LPArray)] byte[] // 其它数组也一样差不多了吧。
    注意:
    1、有字符串的时候 [DllImport("xxx.dll", CharSet = CharSet.Auto)]
    2、字符串常量和字符串缓冲区一定要区别对待,要不然会破坏托管堆。字符串常量没什么说的了,字符串缓冲区的我举个例子:
        StringBuilder sb = new StringBuilder(80); // 缓冲区大小
        xxx(sb,...);
        sb.ToString(); // 再这样得到返回值。
    3、结构体要定义成[StructLayout(LayoutKind.Squential)] struct {...}
    结构体中有字符串的还要这样:
    [StructLayout(LayoutKind.Squential, CharSet = CharSet.Auto)]
    struct
    {
        ...
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] // 长度查MSDN自己定
        string str;
        ...
    }
    结构体中字段的长度一定要对应好,比如BYTE要用byte,SHORT、WORD要用Int16,LONG、DWORD要用int,CHAR要用byte(都是8位,所以楼上xxdneu(xxd)的好像有点儿不对)
    有些时候LayoutKind.Squential并不能解决问题,那样就得用LayoutKind.Explicit,然后每个结构成员添加FieldOffset属性。union 就可以这样处理。
    4、最后,就是最麻烦的void *问题。
    因为C#的类型检查实在是太强了,所有我也没一个很好的解决方案。
    我的经验是在用到void*时,看我要传什么类型的值,那我就把它声明为那个类型的引用,比如ref int。不知上面说的有没有不妥的,在API或者其它非托管库调用有问题的,还可以和我联系
    QQ:25738191 我们一起讨论一下。
      

  6.   

    参数类型:  1、数值型直接用对应的就可。(DWORD -> int , WORD -> Int16)  2、API中字符串指针类型 -> .net中string  3、API中句柄 (dWord) -> .net中IntPtr  4、API中结构 -> .net中结构或者类。注意这种情况下,要先用StructLayout特性限定声明结构或类  公共语言运行库利用StructLayoutAttribute控制类或结构的数据字段在托管内存中的物理布局,即类或结构需要按某种方式排列。如果要将类传递给需要指定布局的非托管代码,则显式控制类布局是重要的。它的构造函数中用LayoutKind值初始化 StructLayoutAttribute 类的新实例。 LayoutKind.Sequential 用于强制将成员按其出现的顺序进行顺序布局。
      

  7.   

    我发现很多人对用字符串都是一概用string,但不对。myxs(魔心)提供的网站的确不错,不过我发现那里也有好多有错误。比如下面那个例子:
    [DllImport("kernel32.dll", SetLastError=true)]
    static extern int GetShortPathName ( 
        string lpszLongPath,
        string lpszShortPath,
        int cchBuffer) 
    我觉得就有问题,应该这样声明:
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern int GetShortPathName (
        [MarshalAs(UnmanagedType.LPTStr)]
        string path,
        [MarshalAs(UnmanagedType.LPTStr)]
        StringBuilder shortPath,
        int shortPathLength);.NET 中字符串类型是不可改变类型,这意味着它的值将永远保持不变。将字符串类型作为缓冲区使用至少会破坏由封送器在转换字符串时创建的临时缓冲区;严重时会破坏托管堆。StringBuilder就是被设计为用作缓冲区的。我的资料摘自MSDN
      

  8.   

    milkbb(李宇杰) 写的很好了,我查到的也差不多就这些:但可能会出现新问题的。
    我还有一个难题:ScanSendCommand(HANDLE hScanner, 
    IN OUT LPTSTR pCmd_CmdResponse, IN OUT int* piLength);上述函数中的IN OUT 在C#中该用什么代替?有资料说用 [IN,OUT]代替? 但好象不对啊。