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

来源:互联网 发布:程序员找工作步骤 编辑:程序博客网 时间:2024/05/19 22:28

    新建项目->VisualC++->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静态链接库时,需要增加程序的依赖性。

常见的类型转换:

基本类型:

HandleIntPtrHwndIntPtrint*ref intint&ref intvoid*IntPtrunsigned char*ref byteBOOLboolDWORDint 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);

枚举类型Win32BOOL 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可用作缓冲区Win32BOOL 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具有内嵌字符数组的结构:Win32typedef 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;}

具有回调的函数Win32BOOL 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(  IntPtrwindowStation,  EnumDesktopProc callback,  int lParam);

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

原创粉丝点击