新建项目->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 或 uint(int 更常用一些) |
| 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*),即对于变长字符串的处理,.net中StringBuilder可用作缓冲区 | |
| 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中“互操作封送处理”一节。

浙公网安备 33010602011771号