Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 为什么我的Fiddle结构中充满了垃圾?_Ruby_Winapi_Fiddle_Ruby Ffi - Fatal编程技术网

Ruby 为什么我的Fiddle结构中充满了垃圾?

Ruby 为什么我的Fiddle结构中充满了垃圾?,ruby,winapi,fiddle,ruby-ffi,Ruby,Winapi,Fiddle,Ruby Ffi,我正试图利用Fiddle将一个非常简单的C Win32 API调用转换为Ruby,但没有取得多大成功 前两个方法调用工作正常,但当我调用填充结构时,我有点困难,因为结构似乎正在填充垃圾数据: 以下是相关的C代码: DWORD dwHandle, dwLen; LPVOID lpData; UINT BufLen; VS_FIXEDFILEINFO *pFileInfo; LPTSTR LibName = L"C:\\windows\\notepad.exe"; dwLen = GetFileV

我正试图利用Fiddle将一个非常简单的C Win32 API调用转换为Ruby,但没有取得多大成功

前两个方法调用工作正常,但当我调用填充结构时,我有点困难,因为结构似乎正在填充垃圾数据:

以下是相关的C代码:

DWORD dwHandle, dwLen;
LPVOID lpData;
UINT BufLen;
VS_FIXEDFILEINFO *pFileInfo;
LPTSTR LibName = L"C:\\windows\\notepad.exe";

dwLen = GetFileVersionInfoSize(LibName, &dwHandle);

if(dwLen != 0) 
{
    lpData = malloc(dwLen);

    if (GetFileVersionInfo(LibName, NULL, &dwLen, lpData)) 
    {
        if (VerQueryValue(lpData, L"\\", (LPVOID)&pFileInfo, (PUINT)&BufLen))
        {
                printf("ProductVersion: %d.%d.%d.%d\n", HIWORD(pFileInfo->dwProductVersionMS), LOWORD(pFileInfo->dwProductVersionLS), HIWORD(pFileInfo->dwFileVersionLS), LOWORD(pFileInfo->dwFileVersionLS));
                printf("FileVersion: %d.%d.%d.%d\n", HIWORD(pFileInfo->dwFileVersionMS), LOWORD(pFileInfo->dwFileVersionMS), HIWORD(pFileInfo->dwFileVersionLS), LOWORD(pFileInfo->dwFileVersionLS));
        }
    }
}
下面是我将C转换为Ruby的尝试:

require 'fiddle/import'

module Version
    extend Fiddle::Importer
    dlload 'version'
    typealias 'HANDLE', 'void*'
    typealias 'LPVOID', 'void*'
    typealias 'LPCVOID', 'const void*'
    typealias 'LPDWORD', 'int*'
    typealias 'HWND', 'HANDLE'
    typealias 'LPCSTR', 'const char*'
    typealias 'LPCWSTR', 'const wchar_t*'
    typealias 'UINT', 'unsigned int'
    typealias 'PUINT', 'unsigned int*'
    typealias 'DWORD', 'unsigned long'
    typealias 'BOOL', 'int'
    extern 'DWORD GetFileVersionInfoSize(LPCSTR, LPDWORD)'
    extern 'BOOL GetFileVersionInfo(LPCSTR, DWORD, DWORD, LPVOID)'
    extern 'BOOL VerQueryValue(LPCVOID, LPCSTR, LPVOID, PUINT)'
    VS_FIXEDFILEINFO = struct [
      'DWORD dwSignature',
      'DWORD dwStrucVersion',
      'DWORD dwFileVersionMS',
      'DWORD dwFileVersionLS',
      'DWORD dwProductVersionMS',
      'DWORD dwProductVersionLS',
      'DWORD dwFileFlagsMask',
      'DWORD dwFileFlags',
      'DWORD dwFileOS',
      'DWORD dwFileType',
      'DWORD dwFileSubtype',
      'DWORD dwFileDateMS',
      'DWORD dwFileDateLS'
    ]
end

dwHandle = Fiddle::NULL
dwLen = Version::GetFileVersionInfoSize "C:\\windows\\system32\\notepad.exe", dwHandle

lpData = Fiddle::Pointer.malloc(dwLen)
Version::GetFileVersionInfo "C:\\windows\\notepad.exe", 0, dwLen, lpData

BufLen = Fiddle::NULL
pFileInfo = Version::VS_FIXEDFILEINFO.malloc()

success = Version::VerQueryValue lpData, "\\", pFileInfo, BufLen.ref

puts "pFileInfo: #{pFileInfo.dwSignature}"
不幸的是,
pFileInfo.dwSignature
似乎每次都在改变,表明它正在被垃圾数据填充(奇怪的是,
VerQueryValue
调用之前它是零)。
pFileInfo.dwSignature
值应始终为
0xFEEF04BD
,或十进制
427707181

你有什么想法吗


谢谢

Fiddle如何处理这样一个事实:在
winapi
中没有名为
GetFileVersionInfoSize
的函数,而是
GetFileVersionInfoSizeW
GetFileVersionInfoSizeA
?您的定义似乎是假设ANSI版本的,对吗?这也是我的第一个想法,尽管Fiddle似乎正确地处理了这种情况。
GetFileVersionInfoSize
GetFileVersionInfo
都采用LPCSTR并生成适当的输出无问题。另一方面,如果
VerQueryValue
收到的字符串类型不是预期的,那么它将失败。例如,在C中,如果您传递一个ANSI字符串,那么函数将失败并返回false。我还想添加一点,即
BufLen
正确返回,而结构中充满了垃圾。