代码拖不托管是浮云:飘过托管的边界

1.托管代码中使用非托管代码

创新互联主要从事网站制作、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务辽阳,10年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:028-86922220

给出个可行示例,简单的说明下下面这段代码的功能--“灰度化”图像。

 
 
 
 
  1. //托管代码调用非托管代码
  2. //DebugLZQ以前写的
  3. //unsafe{}中代码为非托管代码
  4. private void pointer_Click(object sender, EventArgs e)
  5.         {
  6.             if (curBitmap != null)
  7.             {
  8.                 myTimer.ClearTimer();
  9.                 myTimer.Start();
  10.                 Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
  11.                 System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
  12.                 byte temp = 0;
  13.                 unsafe
  14.                 {
  15.                     byte* ptr = (byte*)(bmpData.Scan0);
  16.                     for (int i = 0; i < bmpData.Height; i++)
  17.                     {
  18.                         for (int j = 0; j < bmpData.Width; j++)
  19.                         {
  20.                             temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
  21.                             ptr[0] = ptr[1] = ptr[2] = temp;
  22.                             ptr += 3;
  23.                         }
  24.                         ptr += bmpData.Stride - bmpData.Width * 3;
  25.                     }
  26.                 }
  27.                 curBitmap.UnlockBits(bmpData);
  28.                 myTimer.Stop();
  29.                 timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒"; 
  30.                 Invalidate();
  31.             }
  32.         }

为了使程序能正确执行,需要设置项目的属性生成为:“允许不安全代码”。

这样程序就可正常运行,效果如下:

2.托管代码中使用非托管dll

前面在讲计时器的时候提到过,下面给出一个完整可用的高性能计时器,顺便给出调用非托管dll的示例。代码如下:

  
 
 
 
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.ComponentModel;
  4. using System.Threading;
  5. //DebugLZQ
  6. //www.cnblogs.com/DebugLZQ
  7. //这是使用的一个计时器,拿这个来说明如何在托管代码中使用非托管dll
  8. namespace gray
  9. {
  10.     internal class HiPerfTimer
  11.     {
  12.         [DllImport("Kernel32.dll")]
  13.         private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
  14.         [DllImport("Kernel32.dll")]
  15.         private static extern bool QueryPerformanceFrequency(out long lpFrequency);
  16.         private long startTime, stopTime;
  17.         private long freq;
  18.         // Constructor
  19.         public HiPerfTimer()
  20.         {
  21.             startTime = 0;
  22.             stopTime = 0;
  23.             if (QueryPerformanceFrequency(out freq) == false)
  24.             {
  25.                 // high-performance counter not supported
  26.                 throw new Win32Exception();
  27.             }
  28.         }
  29.         // Start the timer
  30.         public void Start()
  31.         {
  32.             // lets do the waiting threads there work
  33.             Thread.Sleep(0);
  34.             QueryPerformanceCounter(out startTime);
  35.         }
  36.         // Stop the timer
  37.         public void Stop()
  38.         {
  39.             QueryPerformanceCounter(out stopTime);
  40.         }
  41.         // Returns the duration of the timer (in milliseconds)
  42.         public double Duration
  43.         {
  44.             get
  45.             {
  46.                 return (double)(stopTime - startTime) * 1000 / (double)freq;
  47.             }
  48.         }
  49.         public void ClearTimer()
  50.         {
  51.             startTime = 0;
  52.             stopTime = 0;
  53.         }
  54.     }
  55. }

用法很简单:

  
 
 
 
  1. private HiPerfTimer myTimer=new HiPerfTimer();
  2. myTimer.Start();
  3. myTimer.Stop();
  4. myTimer.Duration//wanted

3-4.非托管代码中调用托管dll、写托管代码。

前一篇博文谈到CLR宿主的时候,遇到过这个问题,托管Assembly代码如下:

  
 
 
 
  1. using System;
  2. namespace NET.MST.Eighth.SimpleAssembly
  3. {
  4.     /// 
  5.     /// 一个简单的“托管”程序集,功能是输出传入的字符串
  6.     /// 
  7.     public class SimpleAssembly
  8.     {
  9.         static int WriteString(String s)
  10.         {
  11.             Console.WriteLine("CLR Host Output:" + s);
  12.             return 1;
  13.         }
  14.     }
  15. }

在非托管代码中加载CLR运行托管代码,代码如下:

 
 
 
 
  1. //DebugLZQ
  2. //http://www.cnblogs.com/DebugLZQ
  3. //C++工程中加载CLR,运行托管代码
  4. #include "stdafx.h"
  5. #include 
  6. //这里定义加载哪个版本的CLR
  7. #include    
  8. #pragma   comment(lib,"MSCorEE.lib")
  9. //加载CLR,从而运行托管代码
  10. void main(int argc, _TCHAR* argv[])
  11. {
  12.     ICLRRuntimeHost *pHost;
  13.     HRESULT hr=CorBindToRuntimeEx(
  14.         NULL,
  15.         NULL,
  16. ,
  17.         CLSID_CLRRuntimeHost,
  18.         IID_ICLRRuntimeHost,
  19.         (PVOID*)&pHost);
  20.     
  21.     pHost->Start();
  22.     ICLRControl* clrControl = NULL;
  23.     hr = pHost->GetCLRControl(&clrControl);
  24.     DWORD* returnvalue=NULL;
  25.     //开始运行托管代码
  26.     pHost->ExecuteInDefaultAppDomain(
  27.      L"..\\..\\..\\SimpleAssembly\\bin\\Debug\\SimpleAssembly.dll",
  28.      L"NET.MST.Eighth.SimpleAssembly.SimpleAssembly",
  29.      L"WriteString",
  30.      L"http://www.cnblogs.com/DebugLZQ",
  31.      returnvalue);
  32.     
  33.     system("pause");
  34.     //结束时卸载CLR
  35. }

程序运行结果如下:

   文章旨在给出了一种“托管”--“非托管”互相调用的切实可行的方法,没有什么可圈可点的地方。

文章标题:代码拖不托管是浮云:飘过托管的边界
文章起源:http://www.gawzjz.com/qtweb2/news46/20346.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联