C语言中关于结构体指针使用->调用成员编译器找不到结构体的状况

C语言中关于结构体指针使用->调用成员编译器找不到结构体的情况
最近在看Android NDK,看到C语言部分的demo里有这样一段
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
  JNIEnv *env = NULL;
 
  if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    __android_log_print (ANDROID_LOG_ERROR, "tutorial-1", "Could not retrieve JNIEnv");
    return 0;
  }
  jclass klass = (*env)->FindClass (env, "com/gst_sdk_tutorials/tutorial_1/Tutorial1");
  (*env)->RegisterNatives (env, klass, native_methods, G_N_ELEMENTS(native_methods));
 
  return JNI_VERSION_1_4;
}

这里JavaVM明明是指针,却要用(*vm)->调用函数,这究竟是为什么?我Google出来有人说是不这么写编译器会找不到结构体,这究竟是为什么?我自己写的小测试,在linux下编译好像不会有问题啊,反而是这么写过不了,这里是怎样的结构体?
------解决思路----------------------
取决于JavaVM的定义了
比如重载了operator->
又比如typedef xxx* JavaVM
------解决思路----------------------
假设我有一个函数do_some_thing,需要一个参数,并且这个参数是一个结构体,例如struct SomeType,那么这个函数的声明就是void do_some_thing (struct SomeType t); 当编译器看到这个函数时,必须知道struct SomeType的定义是不是?要不然编译不通过,因为不知道这个参数占用多少内存,要不然函数调用的时候怎么把参数传进去?
现在换种思路,把参数换成指针,就像这样void do_some_thing (struct SomeType *t);当编译器看到这个函数是,发现函数的参数是一个指针,现在编译器不需要知道struct SomeType的定义了,因为在确定的系统中,指针占用的字节数是确定的,32位系统下是4个字节,64位系统下是8个字节,至于指针的类型struct SomeType,编译器是可以忽略的,至少C是这样。
 (*vm)-> 这种写法,显然*vm也是一个指针,vm是一个二级指针,因为只有指针才可以用->操作符。