- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个简单的 GUI 应用程序,它在 Windows 7 x64 上显示一个窗口。我正在使用 FFI 以从 rust 调用 Windows API,但我一直在 ntdll.dll 中获取 SIGSEGV。我做错了什么吗?
完整代码可以在 https://github.com/rillomas/rust_sample 找到,但我会在这里发布主要内容。
rustc -v
的信息如下:
C:\Program Files (x86)\Rust\bin\rustc.exe 0.11-pre-nightly (7d725a3 2014-04-21 23:01:39 -0700)
host: i686-pc-mingw32
#ifndef WINAPI_H_
#define WINAPI_H_
#define UNICODE
#include <windows.h>
#include <stdbool.h>
#define API_CALL_CONVENTION __stdcall
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int width;
int height;
HWND handle;
} WindowContext;
bool API_CALL_CONVENTION createWindow(WindowContext* context, LPCTSTR title);
void API_CALL_CONVENTION mainLoop(WindowContext* context);
#ifdef __cplusplus
}
#endif
#endif // WINAPI_H_
#include "winapi.h"
bool API_CALL_CONVENTION createWindow(WindowContext* context, LPCTSTR title) {
WNDCLASS wnd;
memset(&wnd, 0, sizeof(wnd));
HINSTANCE hInstance = GetModuleHandle(NULL);
wnd.lpfnWndProc = (WNDPROC)DefWindowProc;
wnd.style = CS_OWNDC;
wnd.hInstance = hInstance;
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wnd.lpszMenuName = NULL;
wnd.lpszClassName = TEXT("opengles2.0");
if (!RegisterClass (&wnd) ) {
return false;
}
DWORD wStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION | WS_SIZEBOX;
// Adjust the window rectangle so that the client area has
// the correct number of pixels
RECT windowRect;
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = context->width;
windowRect.bottom = context->height;
BOOL result = AdjustWindowRect(&windowRect, wStyle, FALSE);
if (!result) {
return false;
}
HWND handle = CreateWindow(
TEXT("opengles2.0"),
title,
wStyle,
0,
0,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
NULL,
NULL,
hInstance,
NULL);
// Set the ESContext* to the GWL_USERDATA so that it is available to the
// ESWindowProc
SetWindowLongPtr(handle, GWLP_USERDATA, (LONG) (LONG_PTR) NULL);
if(handle == NULL) {
return false;
}
ShowWindow(handle, TRUE);
context->handle = handle;
return true;
}
void API_CALL_CONVENTION mainLoop(WindowContext* context) {
MSG msg = { 0 };
int done = 0;
// DWORD lastTime = GetTickCount();
while (!done) {
int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0);
// DWORD curTime = GetTickCount();
// float deltaTime = (float)( curTime - lastTime ) / 1000.0f;
// lastTime = curTime;
if ( gotMsg ) {
if (msg.message==WM_QUIT) {
done=1;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
SendMessage( context->handle, WM_PAINT, 0, 0 );
}
// Call update function if registered
// if (esContext->updateFunc != NULL ) {
// esContext->updateFunc ( esContext, deltaTime );
// }
}
}
#![crate_id = "winapi#0.1"]
#![crate_type = "lib"]
extern crate libc;
use libc::types::common::c95::{c_void};
use libc::types::os::arch::c95::{c_int};
use std::ptr::null;
// win32 related types
type LPCWSTR = *u16;
pub type HMODULE = *c_void;
pub struct WindowContext {
pub width: c_int,
pub height: c_int,
pub handle: *c_void
}
#[cfg(windows)]
#[link(name="winapi")]
#[link(name="gdi32")]
extern "stdcall" {
fn createWindow(context: *WindowContext, title: LPCWSTR) -> bool;
fn mainLoop(context: *WindowContext);
}
// #[cfg(target_os = "win32", target_arch = "x86")]
#[cfg(windows)]
#[link(name="kernel32")]
extern "system" {
fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
}
pub fn get_module_handle(name: Option<~str>) -> HMODULE {
match name {
Some(n) => std::os::win32::as_utf16_p(n, |buf| unsafe { GetModuleHandleW(buf) }),
None => unsafe { GetModuleHandleW(null())}
}
}
pub fn create_window(context: *WindowContext, title: ~str) -> bool {
std::os::win32::as_utf16_p(title, |buf| unsafe { createWindow(context, buf) })
}
pub fn main_loop(context: *WindowContext) {
unsafe { mainLoop(context) }
}
extern crate winapi;
use std::ptr::null;
fn main() {
let handle = winapi::get_module_handle(None);
println!("handle: {}", handle);
let context = winapi::WindowContext {
width: 320,
height: 240,
handle: null()
};
let result = winapi::create_window(&context, ~"Sample Window");
if !result {
println!("Failed to create window");
return;
}
winapi::main_loop(&context);
}
PS C:\Users\masato\Documents\GitHub\rust_sample> cmake -G "MinGW Makefiles"
-- The C compiler identification is GNU 4.8.1
-- The CXX compiler identification is GNU 4.8.1
-- Check for working C compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/gcc.exe
-- Check for working C compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/gcc.exe -- w
orks
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/g++.exe
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/g++.exe --
works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/masato/Documents/GitHub/rust_sample
PS C:\Users\masato\Documents\GitHub\rust_sample> mingw32-make.exe
Scanning dependencies of target winapi
[ 50%] Building C object CMakeFiles/winapi.dir/winapi/winapi.c.obj
Linking C static library libwinapi.a
[ 50%] Built target winapi
Scanning dependencies of target winapi_sample
[100%] Building C object CMakeFiles/winapi_sample.dir/winapi_sample.c.obj
C:\Users\masato\Documents\GitHub\rust_sample\winapi_sample.c: In function 'main':
C:\Users\masato\Documents\GitHub\rust_sample\winapi_sample.c:6:5: warning: format '%x' expects argument of type 'unsigne
d int', but argument 2 has type 'HMODULE' [-Wformat=]
printf("Module addres: 0x%x\n", addr);
^
Linking C executable winapi_sample.exe
[100%] Built target winapi_sample
PS C:\Users\masato\Documents\GitHub\rust_sample> rustc winapi.rs
PS C:\Users\masato\Documents\GitHub\rust_sample> rustc .\main.rs -L .
PS C:\Users\masato\Documents\GitHub\rust_sample> gdb .\main.exe
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-w64-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\masato\Documents\GitHub\rust_sample\main.exe...done.
(gdb) r
Starting program: C:\Users\masato\Documents\GitHub\rust_sample\main.exe
[New Thread 7060.0x1a0c]
[New Thread 7060.0x422c]
handle: 0x400000
Program received signal SIGSEGV, Segmentation fault.
0x76f3fc62 in ntdll!ZwMapViewOfSection () from C:\Windows\system32\ntdll.dll
(gdb) bt
#0 0x76f3fc62 in ntdll!ZwMapViewOfSection () from C:\Windows\system32\ntdll.dll
#1 0x76f3fc62 in ntdll!ZwMapViewOfSection () from C:\Windows\system32\ntdll.dll
#2 0x762ceba2 in MapViewOfFile () from C:\Windows\syswow64\KernelBase.dll
#3 0x70a25313 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#4 0x70a251e5 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#5 0x70a253e5 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#6 0x70a25a77 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#7 0x70a25cc4 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#8 0x70a22094 in UxTheme!CloseThemeData () from C:\Windows\SysWOW64\uxtheme.dll
#9 0x70a24260 in UxTheme!IsThemePartDefined () from C:\Windows\SysWOW64\uxtheme.dll
#10 0x70a2421d in UxTheme!IsThemePartDefined () from C:\Windows\SysWOW64\uxtheme.dll
#11 0x70a246ed in UxTheme!ThemeInitApiHook () from C:\Windows\SysWOW64\uxtheme.dll
#12 0x74daacd4 in UnregisterClassW () from C:\Windows\syswow64\user32.dll
#13 0x74daab0e in UnregisterClassW () from C:\Windows\syswow64\user32.dll
#14 0x76f3010a in ntdll!KiUserCallbackDispatcher () from C:\Windows\system32\ntdll.dll
#15 0x0028fa9c in ?? ()
#16 0x74dbc6f1 in USER32!AdjustWindowRect () from C:\Windows\syswow64\user32.dll
#17 0x004cc196 in createWindow@8 (context=0x28fcc8, title=0x9f3618 L"Sample Window")
at C:\Users\masato\Documents\GitHub\rust_sample\winapi\winapi.c:85
#18 0x00403bfd in create_window::closure.1804 ()
#19 0x00403b8a in os::win32::as_utf16_p::h611005080090069878::v0.1 ()
#20 0x00403a2e in create_window::h0d38b3844b04f5aaEba::v0.1 ()
#21 0x0040174c in main::h8f0d1dbc5859ab98gaa::v0.0 ()
#22 0x0042cac8 in start::closure.7798 ()
#23 0x004c035c in rt::task::Task::run::closure.40266 ()
#24 0x004c46b5 in rt::unwind::Unwinder::try::try_fn::hf6246262045efccdJS9::v0.11.pre ()
#25 0x004cc006 in rust_try ()
#26 0x004c0234 in rt::task::Task::run::h08ef5174e2ea21abwj8::v0.11.pre ()
#27 0x0042c97d in start::h07163dfeb7ec96475Ld::v0.11.pre ()
#28 0x0042c829 in lang_start::h59c5ddaef2ad2b17pLd::v0.11.pre ()
#29 0x00401810 in main ()
(gdb)
最佳答案
我发现您的代码存在以下问题:
CreateWindow
是否成功之前调用 SetWindowLongPtr
。x
和 ,您应该将 windowRect.left
和 windowRect.top
传递给 CreateWindow
y
坐标。GetMessage
循环有什么问题?WM_PAINT
消息的代码是错误的。你不能这样做。如果要重绘,请使用 InvalidateRect
。我怀疑以上任何一项都不能解释您的错误。但是,我当然想理清消息循环。它应该看起来像这样:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
如果我使用你的 Win32 C 代码并用我的 C 编译器编译它,那么它运行得很好。这让我认为问题出在您使用的链接过程上。 AdjustWindowRect
中的访问冲突看起来很奇怪。堆栈跟踪有一堆来自主题 API 的函数。你的程序是如何体现的?
关于windows - 创建窗口时 ntdll.dll 中的 SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23239272/
我最近在研究私有(private) API。我尝试在运行时使用 LoadLibrary 和 GetProcAddress 调用 ntdll.dll 中的 NtOpenFile 等函数。幸运的是,它成功
几个星期以来,我遇到了这种情况,这让我非常沮丧, 我的程序调试得很好,没有错误,当我运行程序时,它会执行工作,几秒钟后它终止于“中断继续”选项,当我查看调用堆栈时,事实证明它是来自 ntdll.dll
我链接到 ntdll.lib 以使用 ZwQueryInformationProcess 并使用多线程运行时库。 ntdll 似乎定义了一些crt 函数。因此,当我链接它并使用运行时库时,我会遇到链接
当 ntdll.dll 映射到新进程时,以及任何 ntdll 的进程初始化运行之前,我想使用以下命令闯入 WinDBG。 sxe ld ntdll.dll ;g 然而,这个技巧根本不起作用, ModL
我在调用 Ntdll.dll 的导出方法时遇到了一些问题 在 VS2012 的 Debug模式下,我得到: Run-Time Check Failure #0 - The value of ESP w
我的程序在执行结束时崩溃,甚至看不到堆栈展开信息。我只能看到这个“ntdll!kifastsystemcallret”,有些人可以透露一些信息吗? 最佳答案 KiFastSystemCallRet 表
知道我为什么会收到此错误吗? 这是完整的错误: First-chance exception at 0x77202282 (ntdll.dll) in Test.exe 0xC0000005: Acc
我正在使用带有 boost v1.52.0 的 Visual Studio 2011 C++ 刚刚添加了在子目录中搜索文件的方法,并开始在程序关闭时出现此错误: Unhandled exception
是否有仅使用 ntdll.dll 的 API 调用或任何其他类似方式在堆栈上分配内存? 我知道 alloca() 会这样做,但我不能使用它,因为我只能使用 ntdll.dll 中的函数。 谢谢! 最佳
我正在尝试从 Windows Server 2003 SP2 x86 上的完全转储内存文件转储堆信息。转储是为在 Windows Server 2003 SP2 x64 计算机上运行的 32 位混合(
我正在调试崩溃转储,该转储出现访问冲突异常 (0xC0000005)。 AVE 来自跳转到不属于进程中任何 2 个加载模块的地址: 什么会导致这个过程这么早发生? 该进程似乎正在映射内存 (_ZwCr
当我尝试运行我的程序时,它从未进入 main() 函数,而是挂起。但是,我的程序在多次调用 ntdll.dll 之后,作为堆栈中的第一个调用,我的程序在我的一个类中抛出了异常。异常似乎是导致我的程序因
我正在研究一个小的刚体模拟。我使用 Irrlicht 引擎进行显示,并使用 openMesh 处理网格。 现在我使用 VerySleepy 分析了我的应用程序,发现大部分时间花在了以下函数中(不包括花
我刚刚偶然发现执行此操作 GetModuleHandle("ntdll.dll") 无需事先调用 LoadLibrary("ntdll.dll") . 这意味着 ntdll.dll 已经加载到我的进程
我有一个我编写的应用程序间歇性崩溃,但我无法在应用程序层捕获异常。我总是在事件日志中得到一个条目,但没有给我太多信息: Faulting application name: BCS-UI.exe, v
我目前正致力于通过 dll 注入(inject) Hook ntdll.dll 调用。首先,我通过 CreateRemoteThread() 在现有进程中创建线程然后我通过 LoadLibrary 加
我有以下代码,其中数组在函数中动态声明。以下程序在 Visual Studio 2013 中完美编译。但是,在运行时,代码在打印数组时中断,错误代码如下: 检测到严重错误 c0000374WaveEq
我做了一个非常简单的程序,它为我自动化了一些事情。我用 C++ 编写了它,它在 Windows 上运行。在 Codeblocks IDE 内部使用 GDB 对其进行调试时,我突然得到了许多断点。我不知
我使用 Delphi Sampling Profiler 分析了我的应用程序的一部分. Like most people ,我看到大部分时间都花在了里面 ntdll.dll . Note: i tur
我试图了解 Windows API 如何创建进程,以便我可以创建一个程序来确定无效的 exe 失败的位置。我有一个调用 kernel32.CreateProcessA 的程序。在 OllyDbg 中,
我是一名优秀的程序员,十分优秀!