Ruby FFI:指向无符号整数数组的指针

时间:2014-04-01 14:03:05

标签: c ruby winapi process ffi

我正在尝试在我的ruby程序中使用EnumProcesses

BOOL WINAPI EnumProcesses(
  _Out_  DWORD *pProcessIds,
  _In_   DWORD cb,
  _Out_  DWORD *pBytesReturned
);

我需要定义一个指向无符号整数数组的指针,我是按照以下方式做的:

require 'ffi'

module Win32
  extend FFI::Library
  ffi_lib 'Psapi'
  ffi_convention :stdcall
  attach_function :EnumProcesses,  [:pointer, :uint, :pointer], :int
end

process_ids    = FFI::MemoryPointer.new(:uint, 1024)
bytes_returned = FFI::MemoryPointer.new(:uint)

if Win32.EnumProcesses(process_ids, process_ids.size, bytes_returned) != 0
  puts bytes_returned.read_string
end

返回的上述字节的输出是一种垃圾字符,如x☺

让我知道我在哪里做错了?

1 个答案:

答案 0 :(得分:1)

你非常接近。主要问题是解释从Microsoft返回的数据。它不是一个字符串。它是一个DWORD或uint32s数组。

给出以下内容:

require 'ffi'

module Win32

  extend FFI::Library
  ffi_lib 'Psapi'
  ffi_convention :stdcall

=begin
  BOOL WINAPI EnumProcesses(
    _Out_  DWORD *pProcessIds,
    _In_   DWORD cb,
    _Out_  DWORD *pBytesReturned
  );
=end
  attach_function :EnumProcesses, [:pointer, :uint32, :pointer], :int

end

# Allocate room for the windows process ids.
process_ids = FFI::MemoryPointer.new(:uint32, 1024)

# Allocate room for windows to tell us how many process ids there were.
bytes_returned = FFI::MemoryPointer.new(:uint32)

# Ask for the process ids
if Win32.EnumProcesses(process_ids, process_ids.size, bytes_returned) != 0

  # Determine the number of ids we were given
  process_ids_returned = bytes_returned.read_int / bytes_returned.size

  # Pull all the ids out of the raw memory and into a local ruby array.
  ids = process_ids.read_array_of_type(:uint32, :read_uint32, process_ids_returned)

  puts ids.sort
end