• 用VS2008生成C++代码的dll及在C#中的调用及常见的类型转换


        新建项目->Visual C++->win32->Win32项目->输入项目名称->next->应用程序类型选dll,附加选项选上“导出符号”,添加公共头文件视情况可以加上MFC->完成。
      此时生成的项目有示例代码,可以在原来的代码上修改

      需要注意的是:
        #define 项目名_API extern "C" _declspec(dllimport)  
    原来的宏定义可能不包括extern "C",加上可以被C#等语言调用。

      在C#中调用的时候,把dll放到目录中,
        using System.Runtime.InteropServices;
      然后
        [DllImport("2_channel.dll")]
             public static extern void run();
         即可

      在使用lib静态链接库时,需要增加程序的依赖性。

    常见的类型转换:

    基本类型:

    Handle IntPtr
    Hwnd IntPtr
    int* ref int
    int& ref int
    void* IntPtr
    unsigned char* ref byte
    BOOL bool
    DWORD int  uintint 常用一些
    C++(Win 32) C#
    char** 作为输入参数转为char[]通过Encoding类对这个string[]进行编码后得到的一个char[]
    作为输出参数转为byte[]通过Encoding类对这个byte[]进行解码,得到字符串
    C++ Dll接口
    void CplusplusToCsharp(in char** AgentID, out char** AgentIP);
    C#中的声明
    [DllImport("Example.dll")]
    public static extern void CplusplusToCsharp(char[] AgentID, byte[] AgentIP);
    C#中的调用:
    Encoding encode = Encoding.Default;
    byte[] tAgentID;
    byte[] tAgentIP;
    string[] AgentIP;
    tAgentID = new byte[100];
    tAgentIP = new byte[100];
    CplusplusToCsharp(encode.GetChars(tAgentID), tAgentIP);
    AgentIP[i] = encode.GetString(tAgentIP,i*Length,Length);
    枚举类型 Win32
    BOOL MessageBeep(UINT uType // 声音类型); 其中的声音类型为枚举类型中的某一值。
    C#
    用户需要自己定义一个枚举类型:
    public enum BeepType
    {
      SimpleBeep = -1,
      IconAsterisk = 0x00000040,
      IconExclamation = 0x00000030,
      IconHand = 0x00000010,
      IconQuestion = 0x00000020,
      Ok = 0x00000000,
    }
    C#中导入该函数:
    [DllImport("user32.dll")]
    public static extern bool MessageBeep(BeepType beepType);
    C#中调用该函数:
    MessageBeep(BeepType.IconQuestion);
    结构类型 Win32
    使用结构指针作为参数的函数:
    BOOL GetSystemPowerStatus(
     LPSYSTEM_POWER_STATUS lpSystemPowerStatus
    );
    Win32中该结构体的定义:
    typedef struct _SYSTEM_POWER_STATUS {
    BYTE  ACLineStatus;
    BYTE  BatteryFlag;
    BYTE  BatteryLifePercent;
    BYTE  Reserved1;
    DWORD BatteryLifeTime;
    DWORD BatteryFullLifeTime;
    } SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
    C#
    用户自定义相应的结构体:
    struct SystemPowerStatus
    {
      byte ACLineStatus;
      byte batteryFlag;
      byte batteryLifePercent;
      byte reserved1;
      int batteryLifeTime;
      int batteryFullLifeTime;
    }
    C#中导入该函数:
    [DllImport("kernel32.dll")]
    public static extern bool GetSystemPowerStatus(
      ref SystemPowerStatus systemPowerStatus);
    C#中调用该函数:
    SystemPowerStatus sps;
    ….sps初始化赋值……
    GetSystemPowerStatus(ref sps);
    字符串 对于字符串的处理分为以下几种情况:
    1、  字符串常量指针的处理(LPCTSTR),也适应于字符串常量的处理,.net中的string类型是不可变的类型。
    2、  字符串缓冲区的处理(char*),即对于变长字符串的处理,.netStringBuilder可用作缓冲区
    Win32
    BOOL GetFile(LPCTSTR lpRootPathName);
    C#
    函数声明:
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern bool GetFile (
     [MarshalAs(UnmanagedType.LPTStr)]
     string rootPathName);
    函数调用:
    string pathname;
    GetFile(pathname);
    备注:
    DllImport中的CharSet是为了说明自动地调用该函数相关的Ansi版本或者Unicode版本
     
    变长字符串处理:
    C#
    函数声明:
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern int GetShortPathName(
      [MarshalAs(UnmanagedType.LPTStr)]
      string path,
      [MarshalAs(UnmanagedType.LPTStr)]
      StringBuilder shortPath,
      int shortPathLength);
    函数调用:
    StringBuilder shortPath = new StringBuilder(80);
    int result = GetShortPathName(
    @"d:\test.jpg", shortPath, shortPath.Capacity);
    string s = shortPath.ToString();
    struct 具有内嵌字符数组的结构:
    Win32
    typedef struct _TIME_ZONE_INFORMATION {
      LONG    Bias;
      WCHAR   StandardName[ 32 ];
      SYSTEMTIME StandardDate;
      LONG    StandardBias;
      WCHAR   DaylightName[ 32 ];
      SYSTEMTIME DaylightDate;
      LONG    DaylightBias;
    } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION;
    C#
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct TimeZoneInformation
    {
      public int bias;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
      public string standardName;
      SystemTime standardDate;
      public int standardBias;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
      public string daylightName;
      SystemTime daylightDate;
      public int daylightBias;
    }
    具有回调的函数 Win32
    BOOL EnumDesktops(
     HWINSTA hwinsta,       // 窗口实例的句柄
     DESKTOPENUMPROC lpEnumFunc, // 回调函数
     LPARAM lParam        // 用于回调函数的值
    );
    回调函数DESKTOPENUMPROC的声明:
    BOOL CALLBACK EnumDesktopProc(
     LPTSTR lpszDesktop, // 桌面名称
     LPARAM lParam    // 用户定义的值
    );
    C#
    将回调函数的声明转化为委托:
    delegate bool EnumDesktopProc(
     [MarshalAs(UnmanagedType.LPTStr)]
      string desktopName,
      int lParam);
    该函数在C#中的声明:
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern bool EnumDesktops(
      IntPtr windowStation,
      EnumDesktopProc callback,
      int lParam);

    该表对C#中调用win32函数,以及c++编写的dll时参数及返回值的转换做了一个小的总结,如果想进一步了解这方面内容的话,可以参照msdn中“互操作封送处理”一节。

  • 相关阅读:
    Maintaining Online Redo Log Files
    redo
    SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled
    undo
    HDU_1207_汉诺塔2
    POJ_1611_The Suspect
    POJ_1847_Tram
    POJ_2255_Tree Recovery
    Queries for Number of Palindromes(求任意子列的回文数)
    POJ_1163_The triangle
  • 原文地址:https://www.cnblogs.com/lizi/p/2363181.html
Copyright © 2020-2023  润新知