Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems including header file from different directory [not a path issue]

I've long forgotten c++ and how to use it properly, but now I have to deal with one class and I'm a little bit stuck. So I'm using cocos2dx to write a game for ios, however I am using Lua bindings instead of c++. But... even though, I need to write something that uses JNI so... c/c++ here we come.

I've got the header file and cpp file like this:

DeviceInfoAndroid.h:

#include <jni.h>
#include "../libs/cocos2dx/platform/android/jni/JniHelper.h"

extern "C" {

    const char* getAndroidDeviceId();

}

DeviceInfoAndroid.cpp:

#ifndef _DEVICE_INFO_ANDROID_
#define _DEVICE_INFO_ANDROID_

#include "DeviceInfoAndroid.h"
#include <string>

extern "C" {

const char *getAndroidDeviceId() {
    JniMethodInfo t;
    const char* retVal;
    if (JniHelper::getStaticMethodInfo(t
            , "org/cocos2dx/lib/Cocos2dxActivity" //org/cocos2dx/lib/Cocos2dxActivity
            , "getIMEI"
            , "()Ljava/lang/String;")) {
        jstring jstr;
        jstr = (jstring);
        t.env->CallStaticObjectMethod(t.classID, t.methodID);
        char *cstr;
        cstr = (char *) t.env->GetStringUTFChars(jstr, 0);
        std::string ret(cstr);
        t.env->ReleaseStringUTFChars(jstr, cstr);
        t.env->DeleteLocalRef(jstr);
        retVal = ret.c_str();
    }
    return retVal;
}
}

#endif

I know that all this #ifndef crap is not needed, since I only use this in one place and one place only so no cycle dependencies could occur, but I've added it anyway [it doesn't change when I remove it].

So.. path to the JniHelper.h file is correct. It looks like this btw.:

JniHelper.h

#ifndef __ANDROID_JNI_HELPER_H__
#define __ANDROID_JNI_HELPER_H__

#include <jni.h>
#include <string>
#include "CCPlatformMacros.h"

namespace cocos2d {

    typedef struct JniMethodInfo_
    {
        JNIEnv *    env;
        jclass      classID;
        jmethodID   methodID;
    } JniMethodInfo;

    class CC_DLL JniHelper
    {
    public:
        static JavaVM* getJavaVM();
        static void setJavaVM(JavaVM *javaVM);
        static jclass getClassID(const char *className, JNIEnv *env=0);
        static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
        static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
        static std::string jstring2string(jstring str);

    private:
        static JavaVM *m_psJavaVM;
    };
}

#endif // __ANDROID_JNI_HELPER_H__

Okay.. now.. I use a makefile to build it [it's a part of a larger build process, but for this particular file it looks like this (it is located in the same directory as the .h and .cpp files I pasted here].

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := game_logic

LOCAL_SRC_FILES := \
AppDelegate.cpp \
DeviceInfoAndroid.cpp \
DeviceInfo.cpp \
../libs/lua/cocos2dx_support/LuaEngineImpl.cpp \
../libs/lua/cocos2dx_support/Cocos2dxLuaLoader.cpp \
../libs/lua/cocos2dx_support/LuaCocos2d.cpp \
../libs/lua/cocos2dx_support/LuaEngine.cpp \
../libs/lua/CocosDenshion_support/LuaSimpleAudioEngine.cpp \
../libs/lua/exts/luallthread/llthreads.c \
../libs/lua/exts/luasocket/auxiliar.c \
../libs/lua/exts/luasocket/buffer.c \
../libs/lua/exts/luasocket/except.c \
../libs/lua/exts/luasocket/inet.c \
../libs/lua/exts/luasocket/io.c \
../libs/lua/exts/luasocket/luasocket.c \
../libs/lua/exts/luasocket/mime.c \
../libs/lua/exts/luasocket/options.c \
../libs/lua/exts/luasocket/select.c \
../libs/lua/exts/luasocket/tcp.c \
../libs/lua/exts/luasocket/timeout.c \
../libs/lua/exts/luasocket/udp.c \
../libs/lua/exts/luasocket/unix.c \
../libs/lua/exts/luasocket/usocket.c \
../libs/lua/exts/lualoadexts.c \
../libs/lua/exts/luasocketscripts.c 

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../libs/cocos2dx \
                    $(LOCAL_PATH)/../libs/cocos2dx/platform \
                    $(LOCAL_PATH)/../libs/cocos2dx/include \
                    $(LOCAL_PATH)/../libs/cocos2dx/lua_support \
                    $(LOCAL_PATH)/../libs/CocosDenshion/include \
                    $(LOCAL_PATH)/../libs/lua/lua \
                    $(LOCAL_PATH)/../libs/lua/tolua \
                    $(LOCAL_PATH)/../libs/lua/cocos2dx_support \
                    $(LOCAL_PATH)/../libs/lua/CocosDenshion_support \
    $(LOCAL_PATH)/../libs/lua/exts \
    $(LOCAL_PATH)/../libs/lua/exts/luallthread \
    $(LOCAL_PATH)/../libs/lua/exts/luasocket \
    $(LOCAL_PATH)/../libs/cocos2x/platform/android/jni \

LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../Android/libs/$(TARGET_ARCH_ABI)) \
        -L$(call host-path, $(LOCAL_PATH)/../libs/cocos2dx/platform/third_party/android/libraries/$(TARGET_ARCH_ABI)) -lcurl \
        -lcocos2d \
        -lcocosdenshion \
        -llua

include $(BUILD_SHARED_LIBRARY)

As you can see I've added the path to the JniHelper.h file to the LOCAL_C_INCLUDES. I've tried removing the path and just using "JniHelper.h" but it throws an error saying that file does not exist.

The error I get during build is:

Compile++ thumb  : game_logic <= DeviceInfoAndroid.cpp
jni/../../Classes/DeviceInfoAndroid.cpp: In function 'const char* getAndroidDeviceId()':
jni/../../Classes/DeviceInfoAndroid.cpp:10: error: 'JniMethodInfo' was not declared in this scope
jni/../../Classes/DeviceInfoAndroid.cpp:10: error: expected ';' before 't'
jni/../../Classes/DeviceInfoAndroid.cpp:12: error: 'JniHelper' has not been declared
jni/../../Classes/DeviceInfoAndroid.cpp:12: error: 't' was not declared in this scope
jni/../../Classes/DeviceInfoAndroid.cpp:17: error: expected primary-expression before ')' token
make: *** [obj/local/armeabi/objs-debug/game_logic/DeviceInfoAndroid.o] Error 1

Any tips? What have I done wrong? I know that in order to write in C++ I have a lot to learn, but as I mentioned... I'm not going to write in C++, it's just a few lines of code I need to create for every device type I have to support in my game. I'm already done with objective-c and c++ mixing to get iOS device id.

EDIT: when removing some comments of mine I've managed to remove include of DeviceInfoAndroid.cpp. I've corrected the code above. Sorry about that.

like image 236
Krystian Avatar asked Feb 01 '26 22:02

Krystian


1 Answers

After your edit, here's my updated answer:

JniMethodInfo exists in the namespace cocos2d, so you should reference to it as:

cocos2d::JniMethodInfo t;

Same goes for JniHelper:

if (cocos2d::JniHelper::getStaticMethodInfo etc.

Answer before your edits: (not relevant anymore, but saved here for reference)

You need to move the includes from the header file to the cpp file. DeviceInfoAndroid.h is not automatically included in DeviceInfoAndroid.cpp. You must include it manually.

like image 172
Asaf Avatar answered Feb 04 '26 11:02

Asaf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!