我打算下面的代码
void * ptr1 = VirtualAlloc((void*)0x70000000, 32*1024*1024, MEM_RESERVE, PAGE_READWRITE); void * ptr2 = VirtualAlloc((void*)0x80000000, 4*1024*1024, MEM_RESERVE, PAGE_READWRITE);
但VirtualAlloc失败,ptr1,ptr2的值始终为NULL.我想使用地址0x70000000,0x80000000.有谁知道如何使用这些地址?
我正在尝试调整供应商的c#示例代码,以便与PCI-Express设备连接.代码基本上将一个大缓冲区分配为一个int数组,然后通过fixed关键字将其固定,然后将其交给硬件以填充数据.
这很好用,但它最终失败了,因为.Net仅限于数组中大约20亿个元素.我可以通过使用Long和gcAllowVeryLargeObjects关键字数组将限制推高到16 GB,但最终我仍然遇到.Net限制.
在非托管代码中,我可以调用VirtualAlloc并直接请求40或50GB,但是如果在c#中这是可能的话我不清楚并且我无法找到任何好的示例代码.我意识到我可以用不同的语言来做这件事,但在Windows上至少我对.Net比较熟悉,除了这个程序的这个相对较小的部分外,很少有特定于硬件的代码所以我想要试着坚持我所拥有的.
非常简单的 python 脚本给了我一个访问冲突,我只是不明白为什么。
import ctypes
def Test():
data = bytearray( "\xDE\xAD\xBE\xEF\x0B\xAD\xC0\xDE", 'utf-16' )
dataLen = len( data )
try :
ptr = ctypes.windll.kernel32.VirtualAlloc( ctypes.c_int( 0 ),
ctypes.c_int( dataLen ),
ctypes.c_int( 0x3000 ),
ctypes.c_int( 0x40 ) )
buf = ( ctypes.c_char * dataLen ).from_buffer( data )
ctypes.windll.kernel32.RtlMoveMemory( ctypes.c_int( ptr ),
buf,
ctypes.c_int( dataLen ) )
except Exception as e :
print( e )
exit(-1)
Run Code Online (Sandbox Code Playgroud)
错误:
Traceback (most recent call last):
File "c:\vs17\...\ptvsd_launcher.py", line 119, in <module>
vspd.debug(filename, port_num, debug_id, debug_options, run_as) …Run Code Online (Sandbox Code Playgroud) 我试图在 Windows 应用程序中加载的 DLL 中的某个内存范围内分配一定数量的内存。
我这样做的方式是使用VirtualQuery()搜索标记为空闲且在我需要进行分配的边界内的内存区域。我看到的是,即使该区域被标记为MEM_FREE VirtualAlloc()失败,有时也无法分配内存。
该代码非常接近以下内容:
LPVOID address = NULL, mem = NULL;
for (address = LOWER_RANGE; address < UPPER_RANGE;) {
MEMORY_BASIC_INFORMATION mbi = {0};
if (VirtualQuery(address, &mbi, sizeof(mbi))) {
if (mbi.State == MEM_FREE && mbi.RegionSize >= ALLOC_SIZE) {
mem = VirtualAlloc(address, ALLOC_SIZE,
MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READ);
if (mem) {
break;
}
}
}
address = mbi.BaseAddress + mbi.RegionSize;
}
Run Code Online (Sandbox Code Playgroud)
当VirtualAlloc()失败时,GetLastError()返回ERROR_INVALID_ADDRESS (487).
我解决它的方法是,如果它足够大,则mbi.RegionSize使用页面大小步骤扫描以查找允许我分配所需内存的地址。
为什么根据VirtualQuery整个区域应该是空闲的并且我应该能够在我想要的任何地址内分配,但是通常当第一个VirtualAlloc失败时我必须循环几个步骤直到它最终成功。
virtualalloc ×5
c++ ×2
winapi ×2
c ×1
c# ×1
go ×1
memory ×1
mmap ×1
pointers ×1
python ×1
system-calls ×1
virtualquery ×1