Wu.Country@侠缘

勤学似春起之苗,不见其增,日有所长; 辍学如磨刀之石,不见其损,日所有亏!

导航

C#的非安全代码到底有多大的空间?

  昨天刚在CodeProject上下载了一个关于用C#做快捷键的例子,通过调用user32.Dll和Kernel32.DLL里的函数来实现了这样的功能,今天又在这里(http://www.aaunion.net/cn/blog/more.asp?name=windend&id=323)找到了类似的文章。

有这样的两段相似的代码:
    public class Kernel32
    
{
        [DllImport(
"kernel32.dll")]
        
public static extern int GlobalAddAtom(string Name);
        [DllImport(
"kernel32.dll")]
        
public static extern int GlobalDeleteAtom(int atom);
        [DllImport(
"kernel32.dll")]
        
public static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport(
"kernel32.dll")]
        
public static extern bool GlobalUnlock(IntPtr hMem);
    }


using System.Runtime.InteropServices;
using System;
public unsafe class Memory
{
static int ph = GetProcessHeap();//获得进程堆的句柄
private Memory() {}
public static void* Alloc(int size) //内存分配
{
void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);
if (result == nullthrow new OutOfMemoryException();
return result;
}

public static void Free(void* block) //内存释放
{
if (!HeapFree(ph, 0, block)) throw new InvalidOperationException();
}


const int HEAP_ZERO_MEMORY = 0x00000008;//内存起始地址
[DllImport("kernel32")]
static extern int GetProcessHeap();
[DllImport(
"kernel32")]
static extern void* HeapAlloc(int hHeap, int flags, int size);
[DllImport(
"kernel32")]
static extern bool HeapFree(int hHeap, int flags, void* block);
}

class Test
{
unsafe static void Main() 
{
byte* buffer = (byte*)Memory.Alloc(256);
for (int i = 0; i < 256; i++
buffer[i] 
= (byte)i;
for (int i = 0; i < 256; i++
Console.WriteLine(buffer[i]);
Memory.Free(buffer);
}

}
 

  这里在本质上没有改变什么,都是从windows的核心模块里加载一些API函数,这里又让我想到了API的重要性,如果想用C#写出更好的代码,C++及MFC等一些方面的知识必不可少。

  而我今天所遇到的一个问题就是:如何将一个字符串转化为变量,及一些高级语言里的取地址运算。排除wiki的非安全代码的方法,我没找出更好的方法,而且上面的方法也只是用到了指针,没有用到我所想要的直接把一个字符串转化为变量名的功能。

http://www.msnewsgroups.net/group/microsoft.public.dotnet.languages.csharp/topic1821.aspx

http://www.hightechtalks.com/archive/index.php/t-2093934-re-convert-string-to-variable-contained-in-string.html

找到了一些关于反射的内容,研究了一下,写了一小段代码:
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;
using System.Data;
using System.Data.OleDb;
using System.Globalization;
using System.Reflection;
using System.Security;
using System.Web.UI;


public class Sample
{
    
static public string m_str1    = "This is a test!";
    
public enum Pages
    
{
        page1    
= 1,
        page2    
= 2,
        page3    
= 3
    }


    
unsafe public static void Main()
    
{
        
string m_str1        = "This is a test!";
        
string m_str2        = "m_str1";
        MemberInfo[] m_str3    
= Type.GetType("Sample").GetMember(m_str2);
//        foreach(MemberInfo m_str4 in m_str3)
//        {
//            Console.WriteLine(m_str4.Name);
//        }
//        FieldInfo m_field    = Type.GetType("Sample").GetField(m_str2);
//        Console.WriteLine(m_field.GetValue(m_str2));

        Sample.Pages    m_page    
= new Pages();
        FieldInfo[] m_types        
= m_page.GetType().GetFields();
        
foreach(FieldInfo m_type in m_types)
        
{
            Console.WriteLine(m_type.GetValue(m_page));
        }

        
return;
}

}

利用这样的性质,可以很好的取得编译在DLL里的数据。当然,这里是做为数值类型的数据或者是字符串之类的好处理的,如果是图片等二进制的数据,那就要用资源来编译和引用了。

posted on 2005-12-27 11:04  Wu.Country@侠缘  阅读(749)  评论(0编辑  收藏  举报