托管与非托管
一、概念
(1)托管代码(Managed Code),是在.Net的CLR(Common Language Runtime公共语言运行库)的控制下执行的代码。
(2)托管模块:用托管代码编写的模块,如COM组件,其可通过在VS中“添加引用”的方式加载到项目中,然后添加“using 命名空间”后便可引用其中的类和方法等。
(3)非托管代码(Unmanaged Code),是针对托管代码而言,在CLR控制之外执行的代码。
(4)非托管模块:用非托管代码编写的模块,如C++编写的导出函数dll。
(托管/非托管)代码与(非托管/托管)模块之间的交互是双向的,既可以在托管代码中调用非托管模块,也可以在非托管代码中调用托管模块。二者的交互基于三种支持,即:
(1)平台调用(Platform Invoke),该技术是由.Net的CLR的交互层提供的用以在托管代码中引入各种非托管DLL中封装的函数(包括Windows API函数)的服务。
(2)COM交互(COM interop),该技术是由CLR的交互层提供的用于调用COM接口的
(3)C++交互(C++ interop),该技术是由C++编译器和CLR共同提供的,用于直接在同一个可执行文件中混合非托管代码和托管代码。一般情况下按一定规则包含头文件。
二、二者交互的不同情况下的解决方案
(1)非托管代码调用非托管模块
实例一:在VC中调用非托管DLL。
调用的方式有显式和隐式两种,具体的调用过程参考:http://www.cnblogs.com/Pickuper/articles/2050409.html
(2)非托管代码调用托管模块
待补充……
(3)托管代码调用非托管模块
================================================================================
实例一:在.Net中调用Windows API函数。
用到的交互支持是“平台调用”,平台调用进行的步骤如下:
1.查找包含该函数所在的DLL文件。
2.如果找到,则将该DLL文件加载到内存中。
3.查找函数在内存中的地址并将其参数推到堆栈上,并封送所需的数据。
4.将控制权转移给非托管函数。这样整个函数调用完成。
在C#.Net中,调用Windows API函数的具体实现方法是:
(1)包含System.Runtime.InteropServices命名空间
(2)用DllImport声明包含该API函数的DLL。[DllImport("kernel32.dll")]
(3)用public static extern声明要调用的API函数。public static extern bool MessageBeep(BeepType beepType);
================================================================================
实例二:在.Net中调用自定义导出函数的DLL中的函数。(无源码)
同实例一。
================================================================================ 实例三:在.Net中调用自定义导出类的DLL中的类(无源码)
将该DLL封装一下,或者封装成可导出函数的DLL,封装的时候采取“.h+.lib+.dll”的方式调用需要封装的DLL,并在封装的函数中实
例化,然后调用类的方法。例如,需要封装的DLL中的类Class1中有方法int GetValue(int value),然后定义封装的函数如下:
int GetValuePackage(int value)
{
Class1 class;
return class.GetValue(value);
}
然后将GetValuePackage()声明为导出函数便可在C#中调用
或者封装成可供C#直接引用的COM组件,如OCX等。
================================================================================
实例四:在.Net中调用有源码的非托管模块
将有源码的非托管模块编译为托管模块。
================================================================================
(4)托管代码调用托管模块
参考文献:
《An Overview of Managed/Unmanaged Code Interoperability》http://msdn.microsoft.com/en-us/library/ms973872.aspx
《MS.NET 平台调用、托管DLL、非托管DLL简介》http://www.cnblogs.com/oisiv/archive/2006/04/19/378953.html