问题描述
VB.Net中没有显式地提供对指针的支持,这使访问一些非托管内存或调用一些API有很大的麻烦。在VB6中也有这样的问题,不过在众多高手的研究下,已经可以通过SafeArray模拟实现指针,从而大大提高了内存处理方面的速度。现在想问的是在VB.Net下有没有类似的方式来实现一个指针?也就是利用.Net提供的某些结构或者类型来绕过语言本身直接实现对内存的访问?marshal类里面的内存拷贝函数很麻烦,而且估计效率会很低,所以想要靠指针进行内存操作。
解决方案
解决方案二:
给你个例子参考一下ImportsSystem.Runtime.InteropServicesPrivateDeclareFunctionvAesSetKeyLib"cryp.dll"(ByValptr_OutKeyAsInteger,ByValptr_In_KeyAsInteger,ByValint_KeyLenAsLong)AsBooleanPublicSharedFunctionnAesSetKey(ByRefCtx()AsInteger,ByValAesKey()AsByte)AsBooleanReDimCtx(128)Array.Clear(Ctx,0,Ctx.Length)DimblnRtnAsBoolean=FalseDimAesKeyObjAsGCHandle=GCHandle.Alloc(AesKey,GCHandleType.Pinned)DimAesKeyPtrAsIntPtr=AesKeyObj.AddrOfPinnedObjectDimCtxObjAsGCHandle=GCHandle.Alloc(Ctx,GCHandleType.Pinned)DimCtxPtrAsIntPtr=CtxObj.AddrOfPinnedObjectblnRtn=vAesSetKey(CtxPtr.ToInt32,AesKeyPtr.ToInt32,128)IfAesKeyObj.IsAllocatedThenAesKeyObj.Free()IfCtxObj.IsAllocatedThenCtxObj.Free()AesKeyObj=NothingCtxObj=NothingAesKeyPtr=NothingCtxPtr=NothingReturnblnRtnEndFunction
解决方案三:
呵呵呵呵。。。真的没有吗VB.NET下有可能有点小问题,不过似乎不是很严重,这段时间写一些东西光用些该死的API了,由于根基不好,所以到现在也不懂得API到底干什么了,参数到底咋传。。。。反而沾光了,修改了N多API函数的声明。。。例如:PrivateDeclareFunctionReadProcessMemoryLib"kernel32"(ByValhProcessAsInteger,ByVallpBaseAddressAsInteger,ByVallpBuffer()AsByte,ByValnSizeAsInteger,ByReflpNumberOfBytesWrittenAsInteger)AsIntegerPrivateDeclareFunctionWriteProcessMemoryLib"kernel32"(ByValhProcessAsInt32,ByVallpBaseAddressAsInt32,ByVallpBuffer()AsByte,ByValnSizeAsInt32,ByReflpNumberOfBytesWrittenAsInt32)AsIntegerPrivateDeclareFunctionVirtualQueryExLib"kernel32"(ByValhProcessAsInt32,ByVallpAddressAsIntPtr,ByReflpBufferAsMEMORY_BASIC_INFORMATION,ByValdwLengthAsInt32)AsInt32PrivateDeclareFunctionVirtualProtectExLib"kernel32"(ByValhProcessAsInteger,ByVallpAddressAsIntPtr,ByValdwSizeAsInteger,ByValflNewProtectAsInteger,ByReflpflOldProtectAsInteger)AsInteger这几个API函数用来操作进程内存还是必要的,以上就是VB.NET下我修改的声明了。这时种方式,另外不是可以打包的吗?我觉得打包效率低一些,程序中又是按BYTE操作,就按上面改了,实际上打包也行。再者,System.Runtime.InteropServices名空间下的Marshal里面有很多指针转换的东西,例如前几天写那个该死的屏蔽WIN键的时候,就使用了一个API:SetWindowsHookEx,回调声明成了这个样子:PublicDelegateFunctionHookCallBack(ByValnCodeAsInteger,ByValwParamAsIntPtr,ByVallParamAsIntPtr)AsInteger那在函数处理的时候,就需要从指针转换到结构:PublicStructureKeyboardHookStructPublicvkCodeAsIntegerPublicscanCodeAsIntegerPublicflagsAsIntegerPublictimeAsIntegerPublicdwExtraInfoAsIntegerEndStructure使用DimnewPtrAsKeyboardHookStruct=CType(Marshal.PtrToStructure(lParam,newPtr.GetType()),KeyboardHookStruct)就可以实现转换了。。。。我觉得Marshal还是有用的。。以上只是个人见解,偶是业余爱好者。。。。技术方面谈不到水平啦~~~~:)
解决方案四:
应该可以吧
解决方案五:
谢谢上面诸位的回答,不过现在需要的是一个可以访问内存的指针,而且效率要高,以便在大规模处理内存数据的时候方便。有人知道VB.Net下面的Array具体是什么结构吗?在内存中的结构是什么样子的?
解决方案六:
MARK!!
解决方案七:
顶下,大家一起来讨论啊。昨天做了测试,使用Marshal的WriteByte方法,效率相当的低,比数组访问至少慢700倍。显然不能用它来作为访问内存的工具了。难道真得先把内存从非托管区域Copy过来,处理完了再Copy过去?相当浪费空间啊。
解决方案八:
看来貌似没有人回答了?……