分类目录归档:C# Code

C++ / C# 数据类型对照

C++ 输入输出    C# 
==================================
char chr[255]   O    StringBuilder
KCA_DIR            I    int
LPCSTR             I    string
int                        I    int
LPSTR              O    StringBuilder
int*                      O    out int
DWORD              I    int
DWORD*          O    out int
BOOL                 I    bool
Rc_DBMgr          I    IntPtr
long*                  O    out long
API与C#的数据类型对应关系表
API数据类型类型描述C#类型API数据类型类型描述C#类型
WORD16位无符号整数ushortCHAR字符char
LONG32位无符号整数intDWORDLONG64位长整数long
DWORD32位无符号整数uintHDC设备描述表句柄int
HANDLE句柄,32位整数intHGDIOBJGDI对象句柄int
UINT32位无符号整数uintHINSTANCE实例句柄int
BOOL32位布尔型整数boolHWM窗口句柄int
LPSTR指向字符的32位指针stringHPARAM32位消息参数int
LPCSTR指向常字符的32位指针StringLPARAM32位消息参数int
BYTE字节byteWPARAM32位消息参数int
Wtypes.h 中的非托管类型 非托管 C 语言类型 托管类名 说明
HANDLE void* System.IntPtr 32 位
BYTE unsigned char System.Byte 8 位
SHORT short System.Int16 16 位
WORD unsigned short System.UInt16 16 位
INT int System.Int32 32 位
UINT unsigned int System.UInt32 32 位
LONG long System.Int32 32 位
BOOL long System.Int32 32 位
DWORD unsigned long System.UInt32 32 位
ULONG unsigned long System.UInt32 32 位
CHAR char System.Char 用 ANSI 修饰。
LPSTR char* System.String 或System.StringBuilder 用 ANSI 修饰。
LPCSTR Const char* System.String 或System.StringBuilder 用 ANSI 修饰。
LPWSTR wchar_t* System.String 或System.StringBuilder 用 Unicode 修饰。
LPCWSTR Const wchar_t* System.String 或System.StringBuilder 用 Unicode 修饰。
FLOAT Float System.Single 32 位
DOUBLE Double System.Double 64 位

STDINT.H

typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed __INT64 int64_t;

/* exact-width unsigned integer types */
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __INT64 uint64_t;

/* 7.18.1.2 / / smallest type of at least n bits
/ / minimum-width signed integer types */
typedef signed char int_least8_t;
typedef signed short int int_least16_t;
typedef signed int int_least32_t;
typedef signed __INT64 int_least64_t;

/* minimum-width unsigned integer types */
typedef unsigned char uint_least8_t;
typedef unsigned short int uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned __INT64 uint_least64_t;

/* 7.18.1.3 / / fastest minimum-width signed integer types */
typedef signed int int_fast8_t;
typedef signed int int_fast16_t;
typedef signed int int_fast32_t;
typedef signed __INT64 int_fast64_t;

/* fastest minimum-width unsigned integer types */
typedef unsigned int uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef unsigned __INT64 uint_fast64_t;

typedef signed __INT64 intptr_t;
typedef unsigned __INT64 uintptr_t;

.

C# 调用C++DLL传递指向指针的指针参数的方法

C++结构体定义:

struct DeviceInfo
{    
    char szDeviceName[DEVICE_NAME_LEN];
    char szMACAddress[MAC_ADDRESS_LEN];        
    char szDeviceIP[DEVICE_IP_LEN];
};

C#结构体的定义:

[StructLayout(LayoutKind.Sequential)]
public struct DeviceInfo
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
    public string szDeviceName;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)]
    public string szMACAddress;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
    public string szDeviceIP; 


}

情况1:C++的dll负责分配内存

C++导出函数的声明

#define DLL_API  extern "C"  __declspec(dllexport)
DLL_API int findAllDevices(DeviceInfo** ppDeviceInfoList,int * pCount);

C#导入函数的声明

[DllImport("IPAlter_d.dll")]
public extern static int findAllDevices(out IntPtr pDeviceInfo, ref int pCount);

C#的调用方法:

IntPtr pBuff = new IntPtr();//直接new一个参数即可
 if (IPAlter.findAllDevices(out pBuff, ref cout) != 1)
 {
     System.Console.WriteLine("搜索失败!");
     System.Console.ReadLine();
     return;
 }
 for (int i = 0; i < cout; i++)
 {
IntPtr pPonitor = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(DeviceInfo)) * i);

System.Console.WriteLine(((DeviceInfo)Marshal.PtrToStructure(pPonitor, typeof(DeviceInfo))).szDeviceName); 
 System.Console.WriteLine(((DeviceInfo)Marshal.PtrToStructure(pPonitor, typeof(DeviceInfo))).szDeviceIP); 
 System.Console.WriteLine(((DeviceInfo)Marshal.PtrToStructure(pPonitor, typeof(DeviceInfo))).szMACAddress);
 
 }

情况2:C#负责分配内存

C++导出函数的声明:

DLL_API int findAllDevice(DeviceInfo* ppDeviceInfoList,int * pCount);

 C#导入函数的声明:

[DllImport("IPAlter_d.dll")]
public extern static int findAllDevice(IntPtr pDeviceInfo, ref int pCount);

 C#的调用方法:

DeviceInfo[] DeviceInfoList = new DeviceInfo[50];
 int size = Marshal.SizeOf(typeof(DeviceInfo)) * 50;
 byte[] bytes = new byte[size];
 IntPtr pBuff = Marshal.AllocHGlobal(size);
 if (IPAlter.findAllDevice(pBuff, ref cout) != 1)
 {
     System.Console.WriteLine("搜索失败!");
     System.Console.ReadLine();
     return;
 }
 for (int i = 0; i < cout; i++)
 {

IntPtr pPonitor = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(DeviceInfo)) * i);
 DeviceInfoList[i] = (DeviceInfo)Marshal.PtrToStructure(pPonitor, typeof(DeviceInfo));
 System.Console.WriteLine(DeviceInfoList[i].szDeviceName);
 System.Console.WriteLine(DeviceInfoList[i].szDeviceIP);
 System.Console.WriteLine(DeviceInfoList[i].szMACAddress);


 }
 Marshal.FreeHGlobal(pBuff);

可以参考:

http://www.cnblogs.com/cxwx/archive/2010/12/29/1921140.html

http://hi.baidu.com/fanr520/item/e761f9ca0766d462f6c95d55

http://blog.csdn.net/wangweitingaabbcc/article/details/7663949

C#调用C/C++ DLL方式

1、编写一个简单的DLL

设置为导出函数,并采用C风格。函数前加extern "C" __declspec(dllexport)。定义函数在退出前自己清空堆栈,在函数前加__stdcall。

新建一个头文件,在头文件中:

/* 加入任意你想加入的函数定义*/

extern "C" _declspec(dllexport) int _stdcall add(int *x,int *y); // 声明为C编译、链接方式的外部函数
extern "C" _declspec(dllexport) int _stdcall sub(int x,int y); // 声明为C编译、链接方式的外部函数

新建一个.cpp文件

#include "mydll.h"//貌似这两个头文件的顺序不能颠倒。我试了很多次,但是不能确定。

int add(int *x,int *y)//是否可以理解为,VS2010已经默认是 _stdcall,所以函数不用添加该修饰符
{
return *x+*y;
}

int sub(int x,int y)
{
return x-y;
}

把导出函数名称变为标准名称,需加模块定义文件,就是.def文件。

内容如下:(需要注释,前面加分号就可以了,注释需要单独行)

LIBRARY "TEST"

     EXPORTS

          ;add函数

          add

   ;sub函数

         sub

LIBRARY 库名称

EXPORTS 需要导出的各个函数名称

     重新编译之后,再用Depends工具看一下,函数已经变成标准add。这个在动态加载时很有用,特别是在GetProcAddress函数寻找入库函数的时候。

2、静态调用

新建一个C#的控制台项目,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;//添加

namespace mytest
{
  class Program
  {
    //----------------------------------------------------------------------------------------------
    [DllImport("mydll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
    extern static int add(ref int a, ref int b);

    [DllImport("mydll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
    extern static int sub(int a, int b);
    //--------------------------------------------------------------------------------------------------

    static void Main(string[] args)
    {

      int a, b,c,d;
      a = 1;
      b = 2;
      c=d= 0;

      Console.WriteLine(add(ref a,ref b).ToString());
      Console.WriteLine(sub(b,a).ToString());
      Console.Read();
    }
  }
}

 3、动态调用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;//添加

namespace mytest
{
  class Program
  {

[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(String path);//path 就是dll路径 返回结果为0表示失败。
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);//lib是LoadLibrary返回的句柄,funcName 是函数名称 返回结果为0标识失败。
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);

//声明委托
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
delegate int ADD(ref int x, ref int y);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
delegate int SUB(int x, int y);

static void Main(string[] args)
{

string dllPath = "G:\\VS2010软件学习\\c#调用C_dll\\mytest\\mytest\\mydll.dll";
string apiName1 = "add";
string apiName2 = "sub";
//使用动态加载

IntPtr hLib = LoadLibrary(dllPath);//加载函数

IntPtr apiFunction1 = GetProcAddress(hLib, apiName1);//获取函数地址
IntPtr apiFunction2 = GetProcAddress(hLib, apiName2);//获取函数地址

int i = Marshal.GetLastWin32Error();
if (apiFunction1.ToInt32() == 0)//0表示函数没找到
return;
if (apiFunction2.ToInt32() == 0)//0表示函数没找到
return;

//获取函数接口,相当于函数指针
ADD add1 = (Delegate)Marshal.GetDelegateForFunctionPointer(apiFunction1, typeof(ADD)) as ADD;
SUB sub1 = (SUB)Marshal.GetDelegateForFunctionPointer(apiFunction2, typeof(SUB));

// //调用函数
int a, b,c;
a = 1;
b = 2;
c= 0;
//add1(ref a,ref b);
c=sub1(b,a);
// //释放句柄

FreeLibrary(hLib );

Console.WriteLine(c.ToString());
//Console.WriteLine(add(ref a,ref b).ToString());
//Console.WriteLine(sub(10,2).ToString());
Console.Read();

}

  }
}

注意:

C#时常需要调用C/C++DLL,当传递参数时时常遇到问题,尤其是传递和返回字符串时。VC++中主要字符串类型为:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等,但转为C#类型却不完全相同。

类型对照:

C/C++----------C#

BSTR ---------  StringBuilder

LPCTSTR --------- StringBuilder

LPCWSTR ---------  IntPtr

handle---------IntPtr

hwnd-----------IntPtr

char *----------string

int * -----------ref int

int &-----------ref int

void *----------IntPtr

unsigned char *-----ref byte

Struct需要在C#里重新定义一个Struct

CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);

注意在每个函数的前面加上public static extern +返回的数据类型,如果不加public ,函数默认为私有函数,调用就会出错。

在C#调用C++ DLL封装库时会出现两个问题:

1. 数据类型转换问题 
2. 指针或地址参数传送问题

Application Path

// 获取程序的基目录。
System.AppDomain.CurrentDomain.BaseDirectory

// 获取模块的完整路径。
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName

// 获取和设置当前目录(该进程从中启动的目录)的完全限定目录。
System.Environment.CurrentDirectory

// 获取应用程序的当前工作目录。
System.IO.Directory.GetCurrentDirectory()

// 获取和设置包括该应用程序的目录的名称。
System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase

// 获取启动了应用程序的可执行文件的路径。
System.Windows.Forms.Application.StartupPath

// 获取启动了应用程序的可执行文件的路径及文件名
System.Windows.Forms.Application.ExecutablePath

AppDomain.CurrentDomain.BaseDirectory 返回结果为: D:\mycode\
Application.StartupPath 返回结果为: D:\mycode

.

.

MS.NET 常用注释标签

常见注释标签列表

可用于程序员智能感知或生成类MSDN文档。
列表一:

标签语法 说明 语法 参数

<summary>

<summary> 标记应当用于描述类型或类型成员。使用 <remarks> 添加针对某个类型说明的补充信息。

<summary> 标记的文本是唯一有关 IntelliSense 中的类型的信息源,它也显示在 对象浏览器 中。

<summary>

Description

</summary>

description:对象的摘要。

<remarks>

使用 <remarks>标记添加有关类型的信息,以此补充用 <summary> 指定的信息。此信息显示在对象浏览器中。

<remarks>

Description

</remarks>

description:成员的说明。

<param>

<param> 标记应当用于方法声明的注释中,以描述方法的一个参数。

有关 <param> 标记的文本将显示在 IntelliSense、对象浏览器和代码注释 Web 报表中。

<paramname='name'>

description

</param>

name:方法参数名。将此名称用双引号括起来 (" ")

description:参数说明。

<returns>

<returns> 标记应当用于方法声明的注释,以描述返回值。

<returns>

Description

</returns>

description:返回值的说明。

<value>

<value> 标记使您得以描述属性所代表的值。请注意,当在 Visual Studio .NET 开发环境中通过代码向导添加属性时,它将会为新属性添加 <summary> 标记。然后,应该手动添加 <value> 标记以描述该属性所表示的值。

<value>

property-description

</value>

property-description:属性的说明

<example>

使用 <example> 标记可以指定使用方法或其他库成员的示例。这通常涉及使用 <code> 标记。

<example>

Description

</example>

description: 代码示例的说明。

<c>

<c> 标记为您提供了一种将说明中的文本标记为代码的方法。使用 <code> 将多行指示为代码。

<c>

Text

</c>

text :希望将其指示为代码的文本。

<code>

使用 <code> 标记将多行指示为代码。使用<c>指示应将说明中的文本标记为代码。

<code>

Content

</code>

content:希望将其标记为代码的文本。

<exception>

<exception> 标记使您可以指定哪些异常可被引发。此标记可用在方法、属性、事件和索引器的定义中。

<exception

cref="member">

Description

</exception>

cref:

对可从当前编译环境中获取的异常的引用。编译器检查到给定异常存在后,将 member 转换为输出 XML 中的规范化元素名。必须将 member 括在双引号 (" ") 中。

有关如何创建对泛型类型的 cref 引用的更多信息,请参见 <see>

description:异常的说明。

<see>

<seealso>

<see> 标记使您得以从文本内指定链接。使用 <seealso> 指示文本应该放在“另请参见”节中。

<seecref="member"/>

cref:

对可以通过当前编译环境进行调用的成员或字段的引用。编译器检查给定的代码元素是否存在,并将 member 传递给输出 XML 中的元素名称。应将 member 放在双引号 (" ") 中。

<para>

<para> 标记用于诸如<summary><remarks> <returns> 等标记内,使您得以将结构添加到文本中。

<para>content</para>

content:段落文本。

<code>*

提供了一种插入代码的方法。

<code src="src" language="lan" encoding="c"/>

src:代码文件的位置

language:代码的计算机语言

encoding:文件的编码

<img>*

用以在文档中插入图片

<imgsrc="src"/>

src:图片的位置,相对于注释所在的XML文件

<file>*

用以在文档中插入文件,在页面中表现为下载链接

<filesrc="src"/>

src:文件的位置,相对于注释所在的XML文件

<localize>*

提供一种注释本地化的方法,名称与当前线程语言不同的子节点将被忽略

<localize>

<zh-CHS>中文</zh-CHS>

<en>English</en>

...

</localize>

其它

...

C# LRU

 

using System.Collections.Generic;
using System.Threading;

namespace Lru
{
    public class LRUCache<TKey, TValue>
    {
        const int DEFAULT_CAPACITY = 255;

        int _capacity;
        ReaderWriterLockSlim _locker;
        IDictionary<TKey, TValue> _dictionary;
        LinkedList _linkedList;

        public LRUCache() : this(DEFAULT_CAPACITY) { }

        public LRUCache(int capacity)
        {
            _locker = new ReaderWriterLockSlim();
            _capacity = capacity > 0 ? capacity : DEFAULT_CAPACITY;
            _dictionary = new Dictionary<TKey, TValue>();
            _linkedList = new LinkedList();
        }

        public void Set(TKey key, TValue value)
        {
            _locker.EnterWriteLock();
            try
            {
                _dictionary[key] = value;
                _linkedList.Remove(key);
                _linkedList.AddFirst(key);
                if (_linkedList.Count > _capacity)
                {
                    _dictionary.Remove(_linkedList.Last.Value);
                    _linkedList.RemoveLast();
                }
            }
            finally { _locker.ExitWriteLock(); }
        }

        public bool TryGet(TKey key, out TValue value)
        {
            _locker.EnterUpgradeableReadLock();
            try
            {
                bool b = _dictionary.TryGetValue(key, out value);
                if (b)
                {
                    _locker.EnterWriteLock();
                    try
                    {
                        _linkedList.Remove(key);
                        _linkedList.AddFirst(key);
                    }
                    finally { _locker.ExitWriteLock(); }
                }
                return b;
            }
            catch { throw; }
            finally { _locker.ExitUpgradeableReadLock(); }
        }

        public bool ContainsKey(TKey key)
        {
            _locker.EnterReadLock();
            try
            {
                return _dictionary.ContainsKey(key);
            }
            finally { _locker.ExitReadLock(); }
        }

        public int Count
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _dictionary.Count;
                }
                finally { _locker.ExitReadLock(); }
            }
        }

        public int Capacity
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _capacity;
                }
                finally { _locker.ExitReadLock(); }
            }
            set
            {
                _locker.EnterUpgradeableReadLock();
                try
                {
                    if (value > 0 && _capacity != value)
                    {
                        _locker.EnterWriteLock();
                        try
                        {
                            _capacity = value;
                            while (_linkedList.Count > _capacity)
                            {
                                _linkedList.RemoveLast();
                            }
                        }
                        finally { _locker.ExitWriteLock(); }
                    }
                }
                finally { _locker.ExitUpgradeableReadLock(); }
            }
        }

        public ICollection Keys
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _dictionary.Keys;
                }
                finally { _locker.ExitReadLock(); }
            }
        }

        public ICollection Values
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _dictionary.Values;
                }
                finally { _locker.ExitReadLock(); }
            }
        }
    }
}

 

来源:http://www.itwendao.com/article/detail/243752.html

Authorization

授权模块代码片段:

/// <summary>
    /// HTTP模块默认授权配置
    /// </summary>
    public class Authorization
    {
        Dictionary<string, string> users;
        bool hasValidate;

        /// <summary>
        /// 获取用户总数
        /// </summary>
        public int UserCount
        {
            get
            {
                return this.users.Count;
            }
        }

        /// <summary>
        /// 是否具有验证项
        /// </summary>
        public bool HasValidate
        {
            get { return this.hasValidate; }
        }

        internal Authorization()
        {
            this.users = new Dictionary<string, string>();
            this.LoadUsers("Authorization");
            this.hasValidate = this.users.Count > 0;
        }

        /// <summary>
        /// Authorization
        /// </summary>
        /// <param name="sectionName">配置节名称</param>
        public Authorization(string sectionName)
        {
            if ("Authorization".Equals(sectionName, StringComparison.OrdinalIgnoreCase))
                throw new ArgumentOutOfRangeException("sectionName", "no allows you to define Authorization");

            this.users = new Dictionary<string, string>();
            this.LoadUsers(sectionName);
            this.hasValidate = this.users.Count > 0;
        }

        private void LoadUsers(string sectionName)
        {
            var section = System.Configuration.ConfigurationManager.GetSection(sectionName) as IDictionary;
            if (section != null)
            {
                var enumerator = section.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    this.users.Add(Convert.ToString(enumerator.Key), Convert.ToString(enumerator.Value));
                }
            }
        }

        /// <summary>
        /// 检验是否合法
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns>true 通过 / false 不通过</returns>
        public bool Validate(string username, string password)
        {
            if (this.hasValidate == false)
            {
                //不需要认证
                return true;
            }

            var sourcePassword = "";
            return this.users.TryGetValue(username, out sourcePassword) && sourcePassword.Equals(password);
        }

 

 

CommandLine Parse Code Fragment

Command Line Parse Code Fragment

 

internal class CommandLine
    {
        /// <summary>
        /// get process command line info
        /// </summary>
        /// <param name="processId"></param>
        /// <returns>command line info, array length is 2, ex: ["C:\Windows\system32\svchost.exe","-k LocalService"]</returns>
        public static String[] GetCommandLineInfo(int processId)
        {
            String[] info = new string[2];
            info[0] = "";
            info[1] = "";
            //
            var commandLine = Wmi.GetCommandLine(processId);
            if (commandLine != "")
            {
                info = ParseCommandLine(commandLine);
            }
            return info;
        }

        /// <summary>
        /// get process command line info
        /// </summary>
        /// <param name="commandLine"></param>
        /// <returns>command line info, array length is 2, ex: ["C:\Windows\system32\svchost.exe","-k LocalService"]</returns>
        public static string[] ParseCommandLine(string commandLine)
        {
            string[] info = new String[2];

            //C:\Windows\system32\svchost.exe -k LocalService
            //"C:\Program Files (x86)\Avira\AntiVir Desktop\avgnt.exe" /min

            if (commandLine[0] == '"')
            {
                int end = commandLine.IndexOf('"', 1);
                if (end == -1)
                {
                    info[0] = commandLine;
                    info[1] = "";
                }
                else if (end + 1 < commandLine.Length)
                {
                    info[0] = commandLine.Substring(1, end + 1);
                    info[1] = commandLine.Substring(end + 1).TrimStart(' ');
                }
                else
                {
                    info[0] = commandLine;
                    info[1] = "";
                }
            }
            else
            {
                int pos = commandLine.IndexOf(' ');
                if (pos == -1)
                {
                    info[0] = commandLine;
                    info[1] = "";
                }
                else if (pos + 1 < commandLine.Length)
                {
                    info[0] = commandLine.Substring(0, pos);
                    info[1] = commandLine.Substring(pos + 1).TrimStart(' ');
                }
                else
                {
                    info[0] = commandLine;
                    info[1] = "";
                }
            }

            return info;
        }
    }

 

 

.