使用VariantClear防止内存异常 [英] Use VariantClear to Prevent angainst out o Memory Exception

查看:89
本文介绍了使用VariantClear防止内存异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


out RequestDataVal是Variant.
它返回字符串或单个数组.

在void的每个循环中,可用内存都会缩小,直到出现内存不足异常.

如果我使用VariantClear,则经过几个周期后,我将在executeable中得到一个本机错误异常
异常代码:0xc00000005

dll的开发人员写了以下注释!
请注意,您必须调用VariantClear()到VARIANT.
否则,在数组和字符串的情况下会发生内存泄漏.


有人知道我在这里做错了吗?

谢谢's
de-kekse



Hi,
the out RequestDataVal is a Variant.
It returnes Strings or Single Arrays.

With each cycle of the void read the available Memory shrinks until i get a Out of Memory Exception.

If i use VariantClear i get after a few cycles a native error exception in the executeable
ExceptionCode: 0xc00000005

The developer of the dll wrote the following commment!
Note that you must call VariantClear()to the VARIANT.
Otherwise you will get memory leaks in case of arrays and strings.


Anyone a Idea what i do wrong here?

Thank''s
de-kekse



[System.Runtime.InteropServices.DllImport("oleaut32.dll")]
extern static System.Int32 VariantClear(IntPtr obj);

private System.Single[] _singleArrayRead;
public System.Single[] singleArrayRead
{
	set {_singleArrayRead = value;}
	get { return _singleArrayRead; }
}
private string _StringRead = string.Empty;
public string StringRead
{	set { _StringRead = value; }
	get { return _StringRead; }
}
private static void read()
{
	
	object RequestDataVal;
	
	ReadRequestBlock.GetRequestData(ReadRequestId, out RequestDataVal, out RequestState);
	
    System.TypeCode typecode = System.Type.GetTypeCode(RequestDataVal.GetType());
	switch (typecode)
	{
		case System.TypeCode.Object:
		System.String s = RequestDataVal.GetType().ToString();
		switch (s)
		{ 
			case "System.Single[]":
				_singleArrayRead = (System.Single[])RequestDataVal;
				break;
		}
		case System.TypeCode.String:
			_StringRead = RequestDataVal.ToString();
			break;
	}
	
        // no effect
	// RequestDataVal = null;
	
	// Try to Clear Variant
    System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(RequestDataVal);
    IntPtr RequestDataValPtr = (IntPtr)handle;
    VariantClear(RequestDataValPtr);
    System.Runtime.InteropServices.Marshal.FreeCoTaskMem(RequestDataValPtr);
    RequestDataValPtr = IntPtr.Zero;
	
}

推荐答案

发表评论后,我认为您可以使用以下解决方案解决编组问题:

如果可以更改GetRequestData方法的原型,则可以对其进行更改以输出IntPtr:
After your comment, I think you might solve your marshaling problem with this solution:

If you can change the prototype of the GetRequestData method, you might change it to output an IntPtr:
void GetRequestData(uint p_dwRequestId, out IntPtr p_pReqestDataVal, out ushort p_pwRequestState);



使用Marshal.GetObjectFromNativeVariant方法获取所需的对象,然后使用VariantClear清除变体,并且(如果它在dll中内部分配了变体,请使用Marshal.FreeCoTaskMem释放它.

您的代码应如下所示:



use the Marshal.GetObjectFromNativeVariant method to get the object you expect and then clear the variant with VariantClear and (if it internally allocates the variant in the dll, free it with Marshal.FreeCoTaskMem.

your code should look like:

object RequestDataVal;
IntPtr RequestDataVariant;

ReadRequestBlock.GetRequestData(ReadRequestId, out RequestDataVariant, out RequestState);
RequestDataVal = Marshal.GetObjectForNativeVariant(RequestDataVariant);
// use the RequestDataVal

VariantClear(RequestDataVariant);
Marshal.FreeCoTaskMem(RequestDataVariant);



您可以通过查看封送处理数组来找到更多信息...



you can find more information by looking Marshaling Arrays...


这篇关于使用VariantClear防止内存异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆