Skip to content

Commit 326151c

Browse files
committed
Fix c_char mismatch between std::os::raw and CStr on arm64.
This should only be necessary until rust-lang/rust#29775 lands in stable Rust with 1.6.
1 parent e034af2 commit 326151c

File tree

4 files changed

+34
-16
lines changed

4 files changed

+34
-16
lines changed

src/declare.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ use std::fmt;
4040
use std::mem;
4141
use std::ptr;
4242

43-
use {Encode, Message};
4443
use runtime::{Class, Imp, NO, Object, Sel, self};
4544
use verify::EncodeArguments;
45+
use {Encode, Message};
46+
use to_c_str;
4647

4748
/// An error returned from `MethodImplementation::imp_for` to indicate that a
4849
/// selector and function accept unequal numbers of arguments.
@@ -148,7 +149,7 @@ impl ClassDecl {
148149
let name = CString::new(name).unwrap();
149150
let super_ptr = superclass.map_or(ptr::null(), |c| c);
150151
let cls = unsafe {
151-
runtime::objc_allocateClassPair(super_ptr, name.as_ptr(), 0)
152+
runtime::objc_allocateClassPair(super_ptr, to_c_str(&name), 0)
152153
};
153154
if cls.is_null() {
154155
None
@@ -171,7 +172,7 @@ impl ClassDecl {
171172
};
172173

173174
let success = runtime::class_addMethod(self.cls, sel, imp,
174-
types.as_ptr());
175+
to_c_str(&types));
175176
assert!(success != NO, "Failed to add method {:?}", sel);
176177
}
177178

@@ -191,7 +192,7 @@ impl ClassDecl {
191192
let cls_obj = self.cls as *const Object;
192193
let metaclass = runtime::object_getClass(cls_obj) as *mut Class;
193194
let success = runtime::class_addMethod(metaclass, sel, imp,
194-
types.as_ptr());
195+
to_c_str(&types));
195196
assert!(success != NO, "Failed to add class method {:?}", sel);
196197
}
197198

@@ -203,8 +204,8 @@ impl ClassDecl {
203204
let size = mem::size_of::<T>();
204205
let align = log2_align_of::<T>();
205206
let success = unsafe {
206-
runtime::class_addIvar(self.cls, c_name.as_ptr(), size, align,
207-
encoding.as_ptr())
207+
runtime::class_addIvar(self.cls, to_c_str(&c_name), size, align,
208+
to_c_str(&encoding))
208209
};
209210
assert!(success != NO, "Failed to add ivar {}", name);
210211
}

src/encode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use std::ffi::CStr;
21
use std::fmt;
32
use std::os::raw::{c_char, c_void};
43
use std::str;
54
use malloc_buf::MallocBuffer;
65

76
use runtime::{Class, Object, Sel};
7+
use from_c_str;
88

99
const QUALIFIERS: &'static [char] = &[
1010
'r', // const
@@ -101,7 +101,7 @@ pub fn from_str(code: &str) -> Encoding {
101101
}
102102

103103
pub unsafe fn from_malloc_str(ptr: *mut c_char) -> Encoding {
104-
let s = CStr::from_ptr(ptr);
104+
let s = from_c_str(ptr);
105105
let bytes = s.to_bytes_with_nul();
106106
assert!(str::from_utf8(bytes).is_ok());
107107
let buf = MallocBuffer::new(ptr as *mut u8, bytes.len()).unwrap();

src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,19 @@ mod verify;
6464

6565
#[cfg(test)]
6666
mod test_utils;
67+
68+
// The from_c_str and to_c_str methods are unfortunately needed because,
69+
// prior to Rust 1.6, CStr uses a different definition of c_char than
70+
// std::os::raw on arm64.
71+
// TODO: remove this after most people are on Rust 1.6+
72+
73+
use std::ffi::CStr;
74+
use std::os::raw::c_char;
75+
76+
unsafe fn from_c_str<'a>(ptr: *const c_char) -> &'a CStr {
77+
CStr::from_ptr(ptr as *const _)
78+
}
79+
80+
fn to_c_str(s: &CStr) -> *const c_char {
81+
s.as_ptr() as *const _
82+
}

src/runtime.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! For more information on foreign functions, see Apple's documentation:
44
//! https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html
55
6-
use std::ffi::{CStr, CString};
6+
use std::ffi::CString;
77
use std::fmt;
88
use std::os::raw::{c_char, c_int, c_uint, c_void};
99
use std::ptr;
@@ -12,6 +12,7 @@ use malloc_buf::MallocBuffer;
1212

1313
use encode;
1414
use {Encode, Encoding};
15+
use {from_c_str, to_c_str};
1516

1617
/// The Objective-C `BOOL` type.
1718
///
@@ -158,14 +159,14 @@ impl Sel {
158159
pub fn register(name: &str) -> Sel {
159160
let name = CString::new(name).unwrap();
160161
unsafe {
161-
sel_registerName(name.as_ptr())
162+
sel_registerName(to_c_str(&name))
162163
}
163164
}
164165

165166
/// Returns the name of the method specified by self.
166167
pub fn name(&self) -> &str {
167168
let name = unsafe {
168-
CStr::from_ptr(sel_getName(*self))
169+
from_c_str(sel_getName(*self))
169170
};
170171
str::from_utf8(name.to_bytes()).unwrap()
171172
}
@@ -195,7 +196,7 @@ impl Ivar {
195196
/// Returns the name of self.
196197
pub fn name(&self) -> &str {
197198
let name = unsafe {
198-
CStr::from_ptr(ivar_getName(self))
199+
from_c_str(ivar_getName(self))
199200
};
200201
str::from_utf8(name.to_bytes()).unwrap()
201202
}
@@ -211,7 +212,7 @@ impl Ivar {
211212
/// Returns the `Encoding` of self.
212213
pub fn type_encoding(&self) -> Encoding {
213214
let encoding = unsafe {
214-
CStr::from_ptr(ivar_getTypeEncoding(self))
215+
from_c_str(ivar_getTypeEncoding(self))
215216
};
216217
let s = str::from_utf8(encoding.to_bytes()).unwrap();
217218
encode::from_str(s)
@@ -268,7 +269,7 @@ impl Class {
268269
pub fn get(name: &str) -> Option<&'static Class> {
269270
let name = CString::new(name).unwrap();
270271
unsafe {
271-
let cls = objc_getClass(name.as_ptr());
272+
let cls = objc_getClass(to_c_str(&name));
272273
if cls.is_null() { None } else { Some(&*cls) }
273274
}
274275
}
@@ -292,7 +293,7 @@ impl Class {
292293
/// Returns the name of self.
293294
pub fn name(&self) -> &str {
294295
let name = unsafe {
295-
CStr::from_ptr(class_getName(self))
296+
from_c_str(class_getName(self))
296297
};
297298
str::from_utf8(name.to_bytes()).unwrap()
298299
}
@@ -335,7 +336,7 @@ impl Class {
335336
pub fn instance_variable(&self, name: &str) -> Option<&Ivar> {
336337
let name = CString::new(name).unwrap();
337338
unsafe {
338-
let ivar = class_getInstanceVariable(self, name.as_ptr());
339+
let ivar = class_getInstanceVariable(self, to_c_str(&name));
339340
if ivar.is_null() { None } else { Some(&*ivar) }
340341
}
341342
}

0 commit comments

Comments
 (0)