`
tianshibaijia
  • 浏览: 1154475 次
文章分类
社区版块
存档分类
最新评论

对Marshal(封送)的理解

 
阅读更多

.net Framework是强类型,自动内存回收的平台,对象存储在托管内存中,但是对象的内存布局却对开发者隐藏,甚至是不确定的。即使知道对象的内存布局,.net 也不允许直接操作托管内存,根本没提供操作内存的接口。这是一把双刃剑,对于新应用开发者这是好事,把应用开发和底层内存隔离起来,使得开发者无需了解OS以及内存布局的细节。然后现实世界远远不止.net Framework一个平台,典型的Win32平台上的程序开发者一定要知道数据在内存中的布局。因为.net Framework平台运行于Win32平台之上,所以典型的情况是,一个进程既有非托管内存,又有托管内存。这就很自然地带来了一个问题,那就是数据(对象)如何在非托管内存和托管内存中来回传递。

.net Framework引入了“封送”的概念,并实现了System.Runtime.InteropServerices.Marshal类。具体看来,在非托管内存和非托管内存之间需要传递数据的情况如下:

(1)托管代码需要调用非托管库的函数

这涉及到函数的参数,返回值得封送。

(2)非托管代码调用托管代码函数。

主要是用于回调函数。

(3)托管代码直接操作非托管内存,以获得或设置非托管内存中的数据。

如网际风股票接口,stock.dll负责接收股票数据,并存放于非托管内存中,并把数据的地址通知主程序(假设为托管程序),此时托管代码必须能够读取非托管内存中的数据。Marshal类提供了很多读取非托管内存数据的方法,但要读取结构化的数据,效率最高的还是Marshal.PtrToStructure(),该方法读取非托管内存中的数据,并根据此数据新建并初始化一个对应的托管结构体对象。看起来仿佛很简单,其实并不简单,因为托管和非托管世界里的结构体内存布局完全不同,我们需要显式修饰托管结构体,以使其封送后的内存布局与对应的非托管结构体内存布局完全相同。这需要为结构体及其成员进行封送属性的设定。

暂时先写到这里,现在没有时间继续研究封送了,等完成当前最紧急的任务后,继续我的封送研究,并完成C#程序接收网际风数据的程序。(2010年10月19日)

分享到:
评论

相关推荐

    C#向C++封送结构体数组[归类].pdf

    在跨语言编程中,尤其是当C#需要与C++...这涉及到对C++和C#内存管理的理解,以及熟练使用`Marshal`类提供的方法。在处理包含复杂类型(如数组)的结构体时,尤其需要注意数据的封送方式,以避免数据丢失或内存泄漏。

    marshal.rar

    数据封送(Marshal)是.NET框架中用于在不同上下文、线程或进程之间转换和传输对象的过程。在COM环境中,它是实现跨进程通信(IPC,Inter-Process Communication)的关键步骤。当一个进程的COM对象需要被另一个进程...

    C#—EMguCV Marshal

    其中,`Marshal.StructureToPtr`是一个重要的方法,用于将托管对象中的数据封送到非托管内存块。本文将详细介绍`Marshal.StructureToPtr`方法的功能、参数、异常处理以及注意事项,并通过一个示例帮助理解其实际应用...

    JAXB-Example:一个一般的Java项目,显示JAXB封送处理和取消封送处理

    JAXB提供了一种自动化的机制,用于在Java对象和XML文挡之间进行序列化(封送处理)和反序列化(取消封送处理)。在给定的"JAXB-Example"项目中,我们将深入理解这一过程。 在该项目中,`Client.java`是主程序入口,...

    NET remoting 技术 -1

    - .NET Remoting提供了几种不同类型的对象交互方式,包括传值封送(Marshal by Value)、传引用封送(Marshal by Reference)等。 - 它支持跨进程甚至跨机器的对象调用,使得远程对象可以像本地对象一样被调用。 ...

    C# 程序员参考--平台调用教程

    不过,由于涉及到跨语言和环境的调用,理解封送和异常处理机制至关重要。通过熟练掌握这些技巧,你将能够编写出能够无缝集成托管和非托管代码的应用程序。在实际项目中,记得总是先尝试使用.NET框架提供的托管类,当...

    pinvoke_CSharpe

    由于C#和C++的数据表示方式不同,封送处理是将C#的数据转换为C++可以理解的形式。例如,`MarshalAs`特性可以指定如何转换`string`到`const char*`,或者`struct`到字节数组。 **异常处理** C++的异常不能直接抛给C#...

    C#调用C++的dll.docx

    总之,C#调用C++ DLL涉及到P/Invoke和对非托管代码的理解,通过`[DllImport]`特性声明函数,确保签名匹配,并处理可能的数据类型转换。动态加载则需要使用系统提供的API,但这种方式更为复杂,通常适用于需要灵活...

    全局接口表:一种编组接口指针的简便方法

    此时,全局接口表提供了一种安全的方式来封送和解封送接口,确保其在不同进程间的正确性。 使用全局接口表的主要步骤如下: 1. 创建全局接口表对象:通过CoCreateInstance函数创建ATL提供的IGlobalInterfaceTable...

    C#调用C++版本dll时的类型转换需要注意的问题小结

    在跨语言调用,尤其是C#调用C++...总之,C#调用C++ DLL时的类型转换是一项细致的工作,需要理解两种语言的数据类型、内存布局以及封送规则。通过正确的结构定义、类型映射和错误处理,可以确保跨语言通信的顺利进行。

    TestWinAPI.zip_C#_

    2. **Marshaling(封送处理)**:由于C#和Windows API的数据类型可能不同,封送处理是将C#数据类型转换为API期望格式的过程。C#提供了多种封送规则,比如`MarshalAs`特性,可以显式指定封送类型。 3. **ComImport**...

    c#.net remoting 实例 范例

    - **marshaling(封送处理)**:将对象的状态转换为可以在网络上传输的格式。 2. **工作原理** - **对象透明性**:Remoting使远程对象看起来就像是本地对象一样调用,隐藏了底层的网络通信细节。 - **生命周期...

    c# 调用windows API的实例

    4. **Marshaling(封送处理)**:封送处理是.NET Framework将托管数据类型转换为非托管数据类型的过程。例如,C#的字符串在内存中以Unicode格式存储,而许多API函数期望以ASCII格式的字符数组。为此,我们可以使用`...

    C#中调用Windows API的要点,在.Net Framework SDK文档中,关于调用Windows API的指示

    6. **Marshaling(封送处理)**:.NET Framework会自动处理内存布局和数据类型转换,但这需要正确配置。例如,`IntPtr`用于指针,`[MarshalAs(UnmanagedType.LPTStr)]`用于将C#字符串转换为LPSTR。 7. **错误处理**...

    你必须知道的C#的25个基础概念

    ## C#基础知识详解 1. **静态变量和非静态变量的区别** - 静态变量:在类首次加载时...以上是C#编程中的一些基础概念,理解这些概念对于深入学习和使用C#至关重要。通过实践和不断探索,可以进一步提升C#编程技能。

Global site tag (gtag.js) - Google Analytics