C#调用dll(C++(Win32))时的类型转换总结(转)
http://www.cnblogs.com/lidabo/archive/2012/06/05/2536737.html
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); |
|
Handle |
IntPtr |
Hwnd |
IntPtr |
int* |
ref int |
int& |
ref int |
void* |
IntPtr |
unsigned char* |
ref byte |
BOOL |
bool |
DWORD |
int 或 uint(int 更常用一些) |
枚举类型 |
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)] |
该表对C#中调用win32函数,以及c++编写的dll时参数及返回值的转换做了一个小的总结,如果想进一步了解这方面内容的话,可以参照msdn中"互操作封送处理"一节。
引自:http://blog.csdn.net/xiaochongchong1248/archive/2010/01/12/5181345.aspx
例子:
/// <summary>
/// 定义结构体
/// </summary>
public struct UUID2
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 37)]
public string szID;
}
/// <summary>
/// 声明非托管代码中的方法
/// </summary>
/// <param name="username">用户名</param>
/// <param name="uId">用户编号</param>
/// <returns>标志位 1-成功 0-没有此用户 -1-失败</returns>
[DllImport("Camnpr.dll", EntryPoint = "GetUserID", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 GetUserID(string username, ref UUID2 uId);
/// <summary>
/// 根据用户名获取用户编号
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGetUserID_Click(object sender, EventArgs e)
{
string strPhoneNo = tbPhoneNO.Text.Trim();
UUID2 uId = new UUID2();
Int32 iReturn = GetUserID("camnpr", ref uId);
if (iReturn > 0)
{
tbUserID.Text = uId.szID;
}
else
{
MessageBox.Show(iReturn.ToString());
}
}
C#调用dll(C++(Win32))时的类型转换总结(转)的更多相关文章
- unity 调用 .dll 或 .so时遇到的问题
1.32位的 .dll 无法在64位的unity编辑器下运行. System.DllNotFoundException: xxx , 64位的程序运行32位的dll是会报这种错 2.Failed t ...
- 外壳exe通过反射调用dll时
外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...
- 当程序调用dll时获取dll路径,DLL中获取自身的句柄
当程序调用dll时,获取dll路径的方法: HMODULE hMod = GetModuleHandle(_T("axload.dll")); if (hMod != NULL) ...
- c# 调取 c++ dll____c#调用dll
1.以海康摄像头dll为例.(文章转载https://www.cnblogs.com/smartsensor/p/4343744.html) 海康SDK编程指南 目前使用的海康SDK包括IPC_SDK ...
- 【转】C#调用DLL
C#中如何调用动态链接库DLL(转) 每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍.首先,您需要了解什么是托管,什么是非托管.一般可以认为:非托管代码主要是基 ...
- C#程序实现动态调用DLL的研究(转)
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- 在VC中创建并调用DLL
转自:http://express.ruanko.com/ruanko-express_45/technologyexchange6.html 一.DLL简介 1.什么是DLL? 动态链接库英文为DL ...
- [转]如何在Java中调用DLL方法
转载地址:http://developer.51cto.com/art/200906/129773.htm Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台 ...
- Qt调用dll中的功能函数
声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下: ...
随机推荐
- java中文排序
对中文名称进行排序,不多说,上代码 package test; /** * @Title: Person.java * @Copyright: Copyright (c) 2012-11-19 * @ ...
- java抓取动态生成的网页
最近在做项目的时候有一个需求:从网页面抓取数据,要求是首先抓取整个网页的html源码(后期更新要使用到).刚开始一看这个简单,然后就稀里哗啦的敲起了代码(在这之前使用过Hadoop平台的分布式爬虫框架 ...
- android休眠唤醒流程2
android系统一段时间没有操作, 屏幕(screen)将从高亮(bright)变为暗淡(dim),如果再过段时间还是没有操作,屏幕(screen)从暗淡(dim)变为关闭(off).这时,系 ...
- sqort函数用法总结
qsort包含在<stdlib.h>头文件中,此函数根据你给的比较条件进行快速排序,通过指针移动实现排序.排序之后的结果仍然放在原数组中.使用qsort函数必须自己写一个比较函数. 函数原 ...
- ActiveMQ集群(2)
ActiveMQ具有强大和灵活的集群功能,但在使用的过程中会发现很多的缺点,ActiveMQ的集群方式主要有两种:Master-Slave和Broker Cluster. 1.Master-Slave ...
- Python中的split()函数的使用方法
函数:split() Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(lis ...
- 【C#设计模式——创建型模式】工场方法模式
工场方法模式对简单工场模式进行了乔庙的扩展,不是用一个专门的类来决定实例化哪一个子类.相反,超类把这种决定延迟到每个子类.这种模式实际上没有决策点,就是没有直接选择一个子类实例化的决策. 看书上的例子 ...
- typeof和GetType的区别
http://stackoverflow.com/questions/4537945/what-is-the-difference-of-getting-type-by-using-gettype-a ...
- Python中模拟enum枚举类型的5种方法分享
这篇文章主要介绍了Python中模拟enum枚举类型的5种方法分享,本文直接给出实现代码,需要的朋友可以参考下 以下几种方法来模拟enum:(感觉方法一简单实用) 复制代码代码如下: # way1 ...
- C结构体之位域(位段)
C结构体之位域(位段) 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C ...