*[[Rust:http://www.rust-lang.org/]] [#ybc68f10] #ref(http://upload.wikimedia.org/wikipedia/en/thumb/d/d5/Rust_programming_language_black_logo.svg/200px-Rust_programming_language_black_logo.svg.png,right,around,nolink,Rust) &color(White,#5F2F2F){ ''◆CONTENTS◆'' };&br; #contents *Summary [#jf7ccbcc] -[[The Rust Programming Language:http://www.rust-lang.org/]] -https://github.com/rust-lang/rust --https://github.com/rust-lang/rust/wiki ---https://github.com/rust-lang/rust/wiki/Doc-detailed-release-notes -https://github.com/rust-lang/rust/blob/master/src/liblibc/lib.rs -[[Wikipedia.ja:Rust_(プログラミング言語)]] -http://static.rust-lang.org/doc/master/guide-ffi.html -http://qiita.com/tags/rust -http://wontfix.blogspot.jp/search/label/rust -[[Rust Language Advent Calendar 2014 - Adventar:http://www.adventar.org/calendars/462]] -http://stackoverflow.com/questions/tagged/rust --http://stackoverflow.com/questions/21569718/exit-rust-program-early *[[fwdsumatrapdf>SumatraPDF/fwdsumatrapdf]] &aname(fwdsumatrapdf); [#ge410d95] **Rust 版 [#j7127f95] rustc 0.12.0 (ba4081a5a 2014-10-07 13:44:41 -0700) で動作確認しています.~ Windows PowerShell またはコマンド プロンプトから以下のようにしてビルドします.~ rustc fwdsumatrapdf.rs ---- -fwdsumatrapdf.rs ---- // vim: ts=4 sw=4 expandtab: // rustc fwdsumatrapdf.rs extern crate libc; use libc::{c_int, c_uint, c_short, c_ushort, c_long, c_ulong, c_char, c_void, size_t, wchar_t}; use std::io; use std::os; use std::mem; use std::ptr; static TIMEOUT: c_uint = 10000; static HKEY_LOCAL_MACHINE: u32 = 0x80000002; static KEY_QUERY_VALUE: u32 = 0x01; static KEY_PATH: &'static str = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\SumatraPDF.exe"; static CP_ACP: u32 = 0; static WC_NO_BEST_FIT_CHARS: u32 = 1024; type BOOL = c_int; type LPBOOL = *mut c_int; type UINT = c_uint; type BYTE = u8; type LPBYTE = *mut BYTE; type VOID = c_void; type LPVOID = *mut c_void; type HSZ = LPVOID; type HCONV = LPVOID; type HDDEDATA = LPVOID; type HANDLE = LPVOID; type HKEY = HANDLE; type PHKEY = *mut HKEY; type REGSAM = c_uint; type LONG = c_long; type WORD = u16; type DWORD = c_ulong; type LPWORD = *mut DWORD; type LPDWORD = *mut DWORD; type CCHAR = c_char; type CHAR = c_char; type WCHAR = wchar_t; type LPCWSTR = *const WCHAR; type LPWSTR = *mut WCHAR; type LPCSTR = *const CHAR; type LPSTR = *mut CHAR; type SIZE_T = size_t; struct STARTUPINFOW { cb: DWORD, lpReserved: LPWSTR, lpDesktop: LPWSTR, lpTitle: LPWSTR, dwX: DWORD, dwY: DWORD, dwXSize: DWORD, dwYSize: DWORD, dwXCountChars: DWORD, dwYCountChars: DWORD, dwFillAttribute: DWORD, dwFlags: DWORD, wShowWindow: WORD, cbReserved2: WORD, lpReserved2: LPBYTE, hStdInput: HANDLE, hStdOutput: HANDLE, hStdError: HANDLE } type LPSTARTUPINFOW = *mut STARTUPINFOW; struct PROCESS_INFORMATION { hProcess: HANDLE, hThread: HANDLE, dwProcessId: DWORD, dwThreadId: DWORD } type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION; #[cfg(all(target_os = "windows"))] #[link_name = "advapi32"] #[allow(non_snake_case_functions)] extern "stdcall" { fn RegOpenKeyExW( hKey: HKEY, lpSubKey: LPCWSTR, ulOptions: DWORD, samDesired: REGSAM, phkResult: PHKEY) -> LONG; fn RegQueryValueExW( hKey: HKEY, lpValueName: LPCWSTR, lpReserved: LPDWORD, lpType: LPDWORD, lpData: LPBYTE, lpcbData: LPDWORD) -> LONG; fn RegCloseKey( hKey: HKEY) -> LONG; } #[cfg(all(target_os = "windows"))] #[link_name = "user32"] #[allow(non_snake_case_functions)] extern "stdcall" { fn DdeInitializeW(pidInst: *mut DWORD, pfnCallback: *mut c_void, afCmd: c_uint, ulRes: c_uint) -> c_uint; fn DdeUninitialize(idInst: DWORD) -> c_int; fn DdeCreateStringHandleW(idInst: DWORD, psz: LPWSTR, iCodePage: c_int) -> HSZ; fn DdeFreeStringHandle(idInst: DWORD, hsz: HSZ) -> BOOL; fn DdeCreateDataHandle(idInst: DWORD, pSrc: LPBYTE, cb: DWORD, cbOff: DWORD, hszItem: *const c_int, wFmt: c_uint, afCmd: c_uint) -> HDDEDATA; fn DdeFreeDataHandle(hData: HDDEDATA) -> BOOL; fn DdeConnect(idInst: DWORD, hszService: HSZ, hszTopic: HSZ, pCC: *mut c_void) -> HCONV; fn DdeDisconnect(hConv: HCONV) -> BOOL; fn DdeClientTransaction(pData: LPBYTE, cbData: DWORD, hConv: HCONV, hszItem: *const c_int, wFmt: c_uint, wType: c_uint, dwTimeout: c_uint, pdwResult: *const c_int) -> HDDEDATA; fn WaitForInputIdle(hProcess: HANDLE, dwMilliseconds: DWORD) -> DWORD; } #[cfg(all(target_os = "windows"))] #[link_name = "kernel32"] #[allow(non_snake_case_functions)] extern "stdcall" { fn CreateProcessW( lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, lpProcessAttributes: *const c_int, lpThreadAttributes: *const c_int, bInheritHandles: BOOL, dwCreationFlags: DWORD, lpEnvironment: LPVOID, lpCurrentDirectory: LPCWSTR, lpStartupInfo: LPSTARTUPINFOW, lpProcessInformation: LPPROCESS_INFORMATION) -> BOOL; fn WideCharToMultiByte( CodePage: UINT, dwFlags: DWORD, lpWideCharStr: LPCWSTR, cchWideChar: c_int, lpMultiByteStr: LPSTR, cchMultiByte: c_int, lpDefaultChar: LPCSTR, lpUserdDefaultChar: LPBOOL) -> c_int; } #[allow(non_snake_case_functions)] fn runSumatraPDF() { unsafe { let mut si = STARTUPINFOW { cb: 0, lpReserved: ptr::null_mut(), lpDesktop: ptr::null_mut(), lpTitle: ptr::null_mut(), dwX: 0, dwY: 0, dwXSize: 0, dwYSize: 0, dwXCountChars: 0, dwYCountChars: 0, dwFillAttribute: 0, dwFlags: 0, wShowWindow: 0, cbReserved2: 0, lpReserved2: ptr::null_mut(), hStdInput: ptr::null_mut(), hStdOutput: ptr::null_mut(), hStdError: ptr::null_mut()}; let mut pi = PROCESS_INFORMATION { hProcess: ptr::null_mut(), hThread: ptr::null_mut(), dwProcessId: 0, dwThreadId: 0}; let mut subKey = ptr::null_mut(); let mut dwType = 0u32; let mut sz = 0u32; RegOpenKeyExW(HKEY_LOCAL_MACHINE as HKEY, KEY_PATH.to_utf16().as_ptr(), 0, KEY_QUERY_VALUE, &mut subKey); RegQueryValueExW(subKey, ptr::null(), ptr::null_mut(), &mut dwType, ptr::null_mut(), &mut sz); let mut sumatraPDFRegistry_wchar: Vec<u8> = Vec::from_fn(sz as uint, |idx| 0); RegQueryValueExW(subKey, ptr::null(), ptr::null_mut(), &mut dwType, sumatraPDFRegistry_wchar.as_mut_ptr(), &mut sz); RegCloseKey(subKey); let sumatraPDFRegLength = ((sz - 2) / 2) as c_uint; let mut sumatraPDFRegistry: Vec<u8> = Vec::from_fn(sumatraPDFRegLength as uint, |idx| 0); WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, sumatraPDFRegistry_wchar.as_ptr() as *const u16, -1, sumatraPDFRegistry.as_mut_ptr() as *mut i8, sumatraPDFRegLength as i32, ptr::null(), ptr::null_mut()); let sumatraPDFCommandLine = format!("\"{}\" -reuse-instance", sumatraPDFRegistry.into_ascii().into_string()); si.cb = mem::size_of::<STARTUPINFOW>() as DWORD; CreateProcessW(ptr::null(), sumatraPDFCommandLine.to_utf16().as_mut_ptr(), ptr::null(), ptr::null(), 0, 0, ptr::null_mut(), ptr::null(), &mut si, &mut pi); WaitForInputIdle(pi.hProcess, TIMEOUT); } } #[allow(non_snake_case_functions)] fn ddeExecute(server: &str, topic: &str, command: &str) { unsafe { let appcmd_clientonly = 0x10; let cp_winunicode = 1200; let cf_unicodetext = 13; let xclass_flags = 0x4000; let xtyp_execute = (0x0050 | xclass_flags); let mut idInstance = 0u32; let mut hszServer = ptr::null_mut(); let mut hszTopic = ptr::null_mut(); let mut hConvClient = ptr::null_mut(); let mut hDdeData = ptr::null_mut(); let mut hDdeTransactionData = ptr::null_mut(); loop { DdeInitializeW(&mut idInstance, ptr::null_mut(), appcmd_clientonly, 0); if idInstance == 0u32 { writeln!(io::stderr(), "DdeInitializeW error"); break; } hszServer = DdeCreateStringHandleW(idInstance, server.to_utf16().as_mut_ptr(), cp_winunicode); if hszServer == ptr::null_mut() { writeln!(io::stderr(), "DdeCreateStringHandleW error"); break; } hszTopic = DdeCreateStringHandleW(idInstance, topic.to_utf16().as_mut_ptr(), cp_winunicode); if hszTopic == ptr::null_mut() { writeln!(io::stderr(), "DdeCreateStringHandleW error"); break; } hConvClient = DdeConnect(idInstance, hszServer, hszTopic, ptr::null_mut()); if hConvClient == ptr::null_mut() { writeln!(io::stderr(), "DdeConnect error"); break; } hDdeData = DdeCreateDataHandle(idInstance, command.to_utf16().as_mut_ptr() as LPBYTE, ((command.char_len() + 1)*mem::size_of::<wchar_t>()) as DWORD, 0, ptr::null(), cf_unicodetext, 0); if hDdeData == ptr::null_mut() { writeln!(io::stderr(), "DdeCreateDataHandle error"); break; } hDdeTransactionData = DdeClientTransaction(hDdeData as LPBYTE, -1 as DWORD, hConvClient, ptr::null(), 0, xtyp_execute, TIMEOUT, ptr::null()); if hDdeTransactionData == ptr::null_mut() { writeln!(io::stderr(), "DdeClientTransaction error"); break; } break; } if hDdeTransactionData != ptr::null_mut() { DdeFreeDataHandle(hDdeTransactionData); } if hDdeData != ptr::null_mut() { DdeFreeDataHandle(hDdeData); } if hszServer != ptr::null_mut() { DdeFreeStringHandle(idInstance, hszServer); } if hszTopic != ptr::null_mut() { DdeFreeStringHandle(idInstance, hszTopic); } if hConvClient != ptr::null_mut() { DdeDisconnect(hConvClient); } if idInstance != 0u32 { DdeUninitialize(idInstance); } } } #[allow(non_snake_case)] fn main() { let args = os::args(); if args.len() != 4 { writeln!(io::stderr(), "Usage: {} pdf tex line", args.get(0)); unsafe { libc::exit(2 as libc::c_int); } } let ref pdf = args[1]; let ref tex = args[2]; let ref line = args[3]; let forwardSearch = format!("[ForwardSearch(\"{}\",\"{}\",{},0,0,0)]", pdf, tex, line); runSumatraPDF(); match forwardSearch.to_c_str().as_str() { //Some(ref command) => { // runSumatraPDF(); // ddeExecute("SUMATRA", "control", *command); //}, Some(ref command) => ddeExecute("SUMATRA", "control", *command), None => () } } ----