用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中“互操作封送处理”一节。

转自:http://www.cnblogs.com/lizi/archive/2012/02/22/2363181.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值