代碼拖不托管是浮云:飄過托管的邊界
1.托管代碼中使用非托管代碼
給出個(gè)可行示例,簡(jiǎn)單的說明下下面這段代碼的功能--“灰度化”圖像。
- //托管代碼調(diào)用非托管代碼
- //DebugLZQ以前寫的
- //unsafe{}中代碼為非托管代碼
- private void pointer_Click(object sender, EventArgs e)
- {
- if (curBitmap != null)
- {
- myTimer.ClearTimer();
- myTimer.Start();
- Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
- System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
- byte temp = 0;
- unsafe
- {
- byte* ptr = (byte*)(bmpData.Scan0);
- for (int i = 0; i < bmpData.Height; i++)
- {
- for (int j = 0; j < bmpData.Width; j++)
- {
- temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
- ptr[0] = ptr[1] = ptr[2] = temp;
- ptr += 3;
- }
- ptr += bmpData.Stride - bmpData.Width * 3;
- }
- }
- curBitmap.UnlockBits(bmpData);
- myTimer.Stop();
- timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒";
- Invalidate();
- }
- }
為了使程序能正確執(zhí)行,需要設(shè)置項(xiàng)目的屬性生成為:“允許不安全代碼”。
這樣程序就可正常運(yùn)行,效果如下:
2.托管代碼中使用非托管dll
前面在講計(jì)時(shí)器的時(shí)候提到過,下面給出一個(gè)完整可用的高性能計(jì)時(shí)器,順便給出調(diào)用非托管dll的示例。代碼如下:
- using System;
- using System.Runtime.InteropServices;
- using System.ComponentModel;
- using System.Threading;
- //DebugLZQ
- //www.cnblogs.com/DebugLZQ
- //這是使用的一個(gè)計(jì)時(shí)器,拿這個(gè)來說明如何在托管代碼中使用非托管dll
- namespace gray
- {
- internal class HiPerfTimer
- {
- [DllImport("Kernel32.dll")]
- private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
- [DllImport("Kernel32.dll")]
- private static extern bool QueryPerformanceFrequency(out long lpFrequency);
- private long startTime, stopTime;
- private long freq;
- // Constructor
- public HiPerfTimer()
- {
- startTime = 0;
- stopTime = 0;
- if (QueryPerformanceFrequency(out freq) == false)
- {
- // high-performance counter not supported
- throw new Win32Exception();
- }
- }
- // Start the timer
- public void Start()
- {
- // lets do the waiting threads there work
- Thread.Sleep(0);
- QueryPerformanceCounter(out startTime);
- }
- // Stop the timer
- public void Stop()
- {
- QueryPerformanceCounter(out stopTime);
- }
- // Returns the duration of the timer (in milliseconds)
- public double Duration
- {
- get
- {
- return (double)(stopTime - startTime) * 1000 / (double)freq;
- }
- }
- public void ClearTimer()
- {
- startTime = 0;
- stopTime = 0;
- }
- }
- }
用法很簡(jiǎn)單:
- private HiPerfTimer myTimer=new HiPerfTimer();
- myTimer.Start();
- myTimer.Stop();
- myTimer.Duration//wanted
3-4.非托管代碼中調(diào)用托管dll、寫托管代碼。
前一篇博文談到CLR宿主的時(shí)候,遇到過這個(gè)問題,托管Assembly代碼如下:
- using System;
- namespace NET.MST.Eighth.SimpleAssembly
- {
- /// <summary>
- /// 一個(gè)簡(jiǎn)單的“托管”程序集,功能是輸出傳入的字符串
- /// </summary>
- public class SimpleAssembly
- {
- static int WriteString(String s)
- {
- Console.WriteLine("CLR Host Output:" + s);
- return 1;
- }
- }
- }
在非托管代碼中加載CLR運(yùn)行托管代碼,代碼如下:
- //DebugLZQ
- //http://www.cnblogs.com/DebugLZQ
- //C++工程中加載CLR,運(yùn)行托管代碼
- #include "stdafx.h"
- #include <windows.h>
- //這里定義加載哪個(gè)版本的CLR
- #include <MSCorEE.h>
- #pragma comment(lib,"MSCorEE.lib")
- //加載CLR,從而運(yùn)行托管代碼
- void main(int argc, _TCHAR* argv[])
- {
- ICLRRuntimeHost *pHost;
- HRESULT hr=CorBindToRuntimeEx(
- NULL,
- NULL,
- ,
- CLSID_CLRRuntimeHost,
- IID_ICLRRuntimeHost,
- (PVOID*)&pHost);
- pHost->Start();
- ICLRControl* clrControl = NULL;
- hr = pHost->GetCLRControl(&clrControl);
- DWORD* returnvalue=NULL;
- //開始運(yùn)行托管代碼
- pHost->ExecuteInDefaultAppDomain(
- L"..\\..\\..\\SimpleAssembly\\bin\\Debug\\SimpleAssembly.dll",
- L"NET.MST.Eighth.SimpleAssembly.SimpleAssembly",
- L"WriteString",
- L"http://www.cnblogs.com/DebugLZQ",
- returnvalue);
- system("pause");
- //結(jié)束時(shí)卸載CLR
- }
程序運(yùn)行結(jié)果如下:
文章旨在給出了一種“托管”--“非托管”互相調(diào)用的切實(shí)可行的方法,沒有什么可圈可點(diǎn)的地方。
原文鏈接:http://www.cnblogs.com/DebugLZQ/archive/2012/08/13/2636919.html
【編輯推薦】