-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Corrode does not generate valid argument handling for Windows #140
Comments
True! I wasn't very happy with the amount of OS-specific stuff I did in translating So I guess the way forward here is to guard the current definition of I think maybe it's worth introducing a crate of helpers for Corrode-translated programs, as various people have suggested to me, just to place the I don't know anything about |
Were going to say that envp won't work on windows but it turns out that it actually exists there as well.
Yep.
Not really, it is basically main except it takes |
This is what I have come up with so far which is to just convert the UTF-8 encoded args in rust into wide strings (UCS-2) and then back to the current codepage. If anything fails to convert it simply panics since I haven't been able to figure out what the behaviour should be for that case (and I don't want to spend much time on it either since it is a case where the program is likely broken anyway). Question is, how should this be embedded in the generated corrode sources? Due to its size I'd rather not encode this in AST form as the unix variant. Adding a variant to the Item ast node as #[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
fn main() {
use std::ptr;
use winapi::c_int;
use winapi::winnt::CHAR;
use winapi::winnls::{CP_ACP, CP_UTF8};
use kernel32::{WideCharToMultiByte, MultiByteToWideChar};
unsafe {
let mut args: Vec<_> = ::std::env::args()
.map(|s| {
let size = MultiByteToWideChar(CP_UTF8,
0,
s.as_ptr() as *const CHAR,
s.len() as c_int,
ptr::null_mut(),
0);
if size == 0 {
panic!("MultiByteToWideChar");
}
let mut w_string = Vec::with_capacity(size as usize);
MultiByteToWideChar(CP_UTF8,
0,
s.as_ptr() as *const CHAR,
s.len() as c_int,
w_string.as_mut_ptr(),
size);
w_string.set_len(size as usize);
let size2 = WideCharToMultiByte(CP_ACP,
0,
w_string.as_ptr(),
w_string.len() as c_int,
ptr::null_mut(),
0,
ptr::null(),
ptr::null_mut());
if size2 == 0 {
panic!("WideCharToMultiByte");
}
let mut codepage_string = Vec::with_capacity(size2 as usize);
WideCharToMultiByte(CP_ACP,
0,
w_string.as_ptr(),
w_string.len() as c_int,
codepage_string.as_mut_ptr(),
size2,
ptr::null(),
ptr::null_mut());
codepage_string
})
.collect();
let mut argv: Vec<_> = args.iter_mut().map(|arg| arg.as_mut_ptr()).collect();
// _c_main(argv.len() as c_int, argv.as_mut_ptr());
}
} |
The main function which corrode generates uses
::std::os::unix::ffi::OsStringExt
which does not exist on Windows. The easy way of doing this for Windows would probably be to just pass the UTF-8 encoded arguments to the c main functions which probably works in a lot of cases but will break silently in others. Doing this properly would involve linking against https://crates.io/crates/winapi and converting theOsString
received into the current codepage which I believe will give the same behaviour as the C program http://stackoverflow.com/questions/5408730/what-is-the-encoding-of-argv (though it may obviously be lossy).Potentially it could be useful to detect and generate a wmain function in the c source as well and call into that if it exists.
(I'd link directly to the code but unfortunately that is not possible in markdown files! It's in this section
https://github.com/jameysharp/corrode/blob/e0ad8a9f0bee57e8ad87faf7df1964dae7fe7eff/src/Language/Rust/Corrode/C.md#special-case-translation-for-main)
The text was updated successfully, but these errors were encountered: