- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有以下结构:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WAVEHDR
{
internal IntPtr lpData; // pointer to locked data buffer
internal uint dwBufferLength; // length of data buffer
internal uint dwBytesRecorded; // used for input only
internal IntPtr dwUser; // for client's use
internal uint dwFlags; // assorted flags (see defines)
internal uint dwLoops; // loop control counter
internal IntPtr lpNext; // reserved for driver
internal IntPtr reserved; // reserved for driver
}
我需要分配非托管内存来存储上述结构的实例。指向此结构的指针将传递给 waveOut win32 api 函数(waveOutPrepareHeader、waveOutWrite、waveOutUnprepareHeader)。
Marshal.AllocHGlobal()
还是 Marshal.AllocCoTaskMem()
?有什么区别?sizeof(WAVEHDR)
还是 Marshal.SizeOf(typeof(WAVEHDR))
传递给内存分配方法?有什么区别?注意分配的内存必须固定。
最佳答案
Windows 程序总是至少有两个堆,其中分配了非托管内存。首先是默认进程堆,Windows 在需要代表程序分配内存时使用。第二个是 COM 基础结构用于分配的堆。 .NET P/Invoke 编码器假设此堆被任何非托管代码使用,其函数签名需要取消分配内存。
AllocHGlobal 从进程堆分配,AllocCoTaskMem 从 COM 堆分配。
无论何时编写非托管互操作代码,都应始终避免分配非托管内存的代码与释放它的代码不同的情况。很有可能使用了错误的解除分配器。对于与 C/C++ 程序互操作的任何代码尤其如此。这些程序有自己的分配器,使用自己的堆,由 CRT 在启动时创建。在其他代码中取消分配此类内存是不可能的,您无法可靠地获取堆句柄。这是 P/Invoke 问题的一个非常常见的来源,特别是因为 XP 和更早版本中的 HeapFree() 函数默默地忽略了对未在正确堆中分配的释放内存的请求(泄漏分配的内存),但 Vista 和 Win7 崩溃了程序有异常。
在您的情况下无需担心这一点,您使用的 mmsystem API 函数是干净的。它们旨在确保分配和释放的代码相同。这是您必须调用 waveInPrepareHeader() 的原因之一,它使用最终释放它们的相同代码分配缓冲区。可能使用默认进程堆。
你只需要分配WAVEHDR结构。当你完成它时,你有责任释放它。 mmsystem API 不会为您做这件事,主要是因为它们不能可靠地做到这一点。因此,您可以使用任一分配器,只需确保调用相应的释放方法即可。所有 Windows API 都以这种方式工作。我使用 CoTaskMemAlloc() 但确实没有偏好。只是如果我调用设计糟糕的代码,则更有可能使用 COM 堆。
你不应该在互操作场景中使用 sizeof() 。它返回值类型的托管大小。在 P/Invoke 编码器根据 [StructLayout] 和 [MarshalAs] 指令转换结构类型后,这可能会有所不同。只有 Marshal.SizeOf() 可以为您提供有保证的正确值。
更新:VS2012 中有一个很大的变化。它包含的 C 运行时库现在从默认进程堆分配,而不是使用它自己的堆。从长远来看,这使得 AllocHGlobal 成为最有可能取得成功的途径。
关于c# - Marshal.AllocHGlobal VS Marshal.AllocCoTaskMem,Marshal.SizeOf VS sizeof(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1887288/
在编程环境中是哪一个?有区别吗?我已经看到了这两种方式,我不想在我的代码中拼错它。 最佳答案 编码(marshal)是工作图 block ;例如,消防编码(marshal)或美国编码(marshal)
我有以下结构: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WAVEHDR { in
我找不到以下问题的明确答案:如果一个 COM 类是线程安全的,即它被标记为 Both 或 Free,我真的需要编码它的对象接口(interface)以将它传递给另一个线程吗?相同的过程?我不问两个线程
在编译 C# ASP.NET 应用程序时,我从 Visual Studio 2008 中收到奇怪的警告。谁能告诉我这个警告的含义(如果可能的话,用几个音节的词)? At least one of th
TL;DR:MongoDB 驱动程序是否提供了编码和解码文档单个字段的功能? 这是一个非常简单的问题,但这里有一些上下文: 我有一个工作人员负责在 2 个独立的数据库之间同步数据。当它接收到事件消息时
是否可以在使用自定义编码(marshal)拆收器的结构上使用 Marshal.SizeOf()? 例如: struct Abcde { public int test1; [MarshalAs
我有一张 map :[]map[string]string . 将结果填充到 json.marshal()兼容的对象。输出: [ { "key1": "val1", "key2":
如何在没有根元素的情况下进行编码(marshal)? type Ids struct { Id []string `xml:"id"` } IdsStr, _ := xml.Marshal(&Id
我有这个 C++ 代码: extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo) { *foo =
我创建了 map[string]interface{} 并且我想通过 2 个重置服务之间的映射传递多种类型。 每次我编码时,我都会在应该包含 reflect.Type 的字段中得到空映射。 Servi
我有一个托管的 .Net 类,它创建了我需要确保正确清理的非托管资源。 我有一个顺序结构: [StructLayout(LayoutKind.Sequential)] struct FooBar {
我在用 val akkaV = "2.2.3" val sprayV = "1.2.0" Seq( "io.spray" % "spray-can" % spra
我正在使用 Castor 编码/取消编码我的 Java 对象,其中一个对象包含一个 EnumMap。Castor 可以编码(marshal)/解封 EnumMaps 吗?我有一个带有一些嵌套 Hash
错误:com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException:无法编码类型类 [Ljava.lang.Strin
我们在 netbeans 中做了一次 cleanbuild,检查了 jdk 版本并在服务器上部署了所有内容,但仍然出现以下错误。有人可以帮忙吗? javax.servlet.ServletExcept
我想知道是否可以对我的类进行注释,以便编码器第一次遇到对象时,它会生成适当类型的 XML 元素,但任何其他对该对象的后续引用都将具有 XML IDREF条目已创建? 最佳答案 您可以利用 JAXB 的
我正在从现有代码构建一个通用类库,但我收到了一些编译器警告,提示我终其一生都不知道该如何处理。 我有这样的代码: void SomeMethod(Object data) { var size =
我在编码我的 JAXBElement 时遇到了这个异常,它有几个子元素。我如何弄清楚如何查明导致此异常的子元素? java.lang.NullPointerException at com.s
本文整理了Java中org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller.marshall()方法的一些代码示例,展示
我最近已经问了一个有关 JAXB 的问题,可以在以下位置找到:How to marshal/unmarshal Java objects with private fields using JAXB
我是一名优秀的程序员,十分优秀!