rust-mobile / android-activity

Glue for building Rust applications on Android with NativeActivity or GameActivity
238 stars 46 forks source link

Having some trouble understanding the relationship between `*mut ffi::AndroidApp`, `*mut ndk_sys::ANativeActivity`, and `AndroidApp` #127

Closed ArthurKValladares closed 11 months ago

ArthurKValladares commented 11 months ago

Hello,

I currently use this crate trough winit to initialize my Rust Android project, and I am running into some trouble getting the AndroidApp api to work with the GooglePlayGames library that I need to use in my game (trough C ffi). The library gpg allows us to use 3 different initialization functions, two of them I see can be made to match either the android-activity or the native-activity modules: https://developers.google.com/games/services/cpp/api/struct/gpg/android-initialization

void gpg::AndroidInitialization::ANativeActivity_onCreate(
  ANativeActivity *native_activity,
  void *savedState,
  size_t savedStateSize
)

which has the same signature as the entry point for native-activity:

extern "C" fn ANativeActivity_onCreate(
    activity: *mut ndk_sys::ANativeActivity,
    saved_state: *const libc::c_void,
    saved_state_size: libc::size_t,
)

or:

void gpg::AndroidInitialization::android_main(
  struct android_app *app
)

which has the same signature as the entry-point for game-activity:

pub unsafe extern "C" fn _rust_glue_entry(app: *mut ffi::android_app)

The second part of the gpg API comes in the AndroidPlarformConfiguration::SetActivity function, where I must pass in an activity that will be active for the lifetime of your application: https://developers.google.com/games/services/cpp/api/class/gpg/android-platform-configuration#classgpg_1_1_android_platform_configuration_1a88c2011548eb4329c38f2a11e35c787c

AndroidPlatformConfiguration & SetActivity(
  jobject android_app_activity
)

The only way I currently see to set this activity is by using the android_app* pointer passed in to us trough the game-activity module.:

gpg::AndroidPlatformConfiguration platform_configuration;
platform_configuration.SetActivity(android_app->activity->clazz);

Is there a inherent reason why this app pointer is not accessible trough the native-activity module? My application currently relies on some NativeActivity functionality, and from the gpg::AndroidInitialization documentation it seems like it should be possible to obtain the android_app* while still using a NativeActivity.

I don't need support for this specific behavior to be supported in the crate itself, I'm more than happy to add a declaration like:

extern "Rust" {
    pub fn android_main_native(app: *mut ffi::android_app);
}

to a local branch so I can call the C ffi initialization code from a app-side defined function. I would just appreciate some more context into how to make this work, and some pointers on what to do if the best course of action is modifying a local branch.

Thank you so much, and sorry for the very long and specific issue.

MarijnS95 commented 11 months ago

Is there a inherent reason why this app pointer is not accessible trough the native-activity module? My application currently relies on some NativeActivity functionality, and from the gpg::AndroidInitialization documentation it seems like it should be possible to obtain the android_app* while still using a NativeActivity.

Because native-activity implements the glue layer in pure Rust rather than cross-compiling the C code like game-activity. Hence there's no android_app type which belongs to this glue layer, and there is instead a similar struct to store similar members in Rust'y form.

In fact, all that function probably does is pull out the three arguments for gpg::AndroidInitialization::ANativeActivity_onCreate() from struct android_app:

https://cs.android.com/android/platform/superproject/+/master:prebuilts/ndk/current/sources/android/native_app_glue/android_native_app_glue.h;l=124-138;drc=98d43080f2d0a79b8fa5d74b29a9155d67909fd0

ArthurKValladares commented 11 months ago

Thank you, I understand it now.