diff options
| author | Teddy Wing | 2018-10-05 23:07:14 +0200 | 
|---|---|---|
| committer | Teddy Wing | 2018-10-05 23:07:14 +0200 | 
| commit | c231864f9a8c5242d2877ad56f069199082e78b1 (patch) | |
| tree | c4f16e2d6146af9f3d7fca7e4725ba15ae0c428c /src | |
| parent | 9ec2632bb036defc9f5706c1f38981dc4eb55afe (diff) | |
| download | dome-key-map-c231864f9a8c5242d2877ad56f069199082e78b1.tar.bz2 | |
Fix command line argument FFI issues
I was getting this error when I brought the library into the Objective-C
application:
    Undefined symbols for architecture x86_64:
      "_parse_args", referenced from:
          _main in main.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
Ended up renaming my FFI function to `c_parse_args()` (like with
`c_run_key_action()`) which fixed this. Going to have to rename those to
use a `dome_key_` prefix eventually.
Then, my `args` argument didn't have the right type. It had a `*const
c_char` type, which is a string, when it should have been an array of
strings. We just needed a double pointer. A Stack Overflow answer from
Tibor Benke (https://stackoverflow.com/users/3989982/tibor-benke) proved
helpful in this regard:
    fn foo(argc: c_int, argv: *const *const c_char);
https://stackoverflow.com/questions/34379641/how-do-i-convert-rust-args-into-the-argc-and-argv-c-equivalents/34379937#34379937
Update the `map()` call to account for the new type, and check that we
don't have any null pointers within the array.
Finally, shift the first (command name) argument off the list when
parsing options as suggested in the 'getopts' doc example.
Diffstat (limited to 'src')
| -rw-r--r-- | src/cocoa_bridge.rs | 13 | ||||
| -rw-r--r-- | src/config.rs | 2 | 
2 files changed, 9 insertions, 6 deletions
| diff --git a/src/cocoa_bridge.rs b/src/cocoa_bridge.rs index 529fb5d..2ef4979 100644 --- a/src/cocoa_bridge.rs +++ b/src/cocoa_bridge.rs @@ -299,8 +299,8 @@ fn run_action(map_action: &MapAction) {  // }  #[no_mangle] -pub extern "C" fn parse_args( -    args: *const c_char, +pub extern "C" fn c_parse_args( +    args: *const *const c_char,      length: size_t,  ) -> *const Config {      let args = unsafe { @@ -310,10 +310,13 @@ pub extern "C" fn parse_args(          args              .iter() -            .map(|s| -                CStr::from_ptr(s) +            .map(|s| { +                assert!(!s.is_null()); + +                CStr::from_ptr(*s)                      .to_string_lossy() -                    .into_owned()) +                    .into_owned() +            })              .collect::<Vec<String>>()      }; diff --git a/src/config.rs b/src/config.rs index b7b09ab..6ee2d17 100644 --- a/src/config.rs +++ b/src/config.rs @@ -25,7 +25,7 @@ pub fn parse_args(args: &[String]) -> Config {      opts.optflag("r", "reload-mappings", "reload the mappings file");      opts.optflag("h", "help", "print this help menu"); -    let matches = match opts.parse(args) { +    let matches = match opts.parse(&args[1..]) {          Ok(m) => m,          Err(e) => panic!(e),      }; | 
