1.托管代码中使用非托管代码
给出个可行示例,简单的说明下下面这段代码的功能--“灰度化”图像。
- //托管代码调用非托管代码
- //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();
- }
- }
为了使程序能正确执行,需要设置项目的属性生成为:“允许不安全代码”。
这样程序就可正常运行,效果如下:
2.托管代码中使用非托管dll
前面在讲计时器的时候提到过,下面给出一个完整可用的高性能计时器,顺便给出调用非托管dll的示例。代码如下:
- using System;
- using System.Runtime.InteropServices;
- using System.ComponentModel;
- using System.Threading;
- //DebugLZQ
- //www.cnblogs.com/DebugLZQ
- //这是使用的一个计时器,拿这个来说明如何在托管代码中使用非托管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;
- }
- }
- }
用法很简单:
- private HiPerfTimer myTimer=new HiPerfTimer();
- myTimer.Start();
- myTimer.Stop();
- myTimer.Duration//wanted
3-4.非托管代码中调用托管dll、写托管代码。
前一篇博文谈到CLR宿主的时候,遇到过这个问题,托管Assembly代码如下:
- using System;
- namespace NET.MST.Eighth.SimpleAssembly
- {
- /// <summary>
- /// 一个简单的“托管”程序集,功能是输出传入的字符串
- /// </summary>
- public class SimpleAssembly
- {
- static int WriteString(String s)
- {
- Console.WriteLine("CLR Host Output:" + s);
- return 1;
- }
- }
- }
在非托管代码中加载CLR运行托管代码,代码如下:
- //DebugLZQ
- //http://www.cnblogs.com/DebugLZQ
- //C++工程中加载CLR,运行托管代码
- #include "stdafx.h"
- #include <windows.h>
- //这里定义加载哪个版本的CLR
- #include <MSCorEE.h>
- #pragma comment(lib,"MSCorEE.lib")
- //加载CLR,从而运行托管代码
- 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;
- //开始运行托管代码
- 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");
- //结束时卸载CLR
- }
程序运行结果如下:
文章旨在给出了一种“托管”--“非托管”互相调用的切实可行的方法,没有什么可圈可点的地方。
原文链接:http://www.cnblogs.com/DebugLZQ/archive/2012/08/13/2636919.html
【编辑推荐】