gpt4 book ai didi

java - Android NDK - 在 native 函数中引用 C++ 类

转载 作者:行者123 更新时间:2023-11-30 02:45:37 25 4
gpt4 key购买 nike

我是 Android NDK 的新手,遇到以下问题。

我的 JNI 文件夹中有一个名为“get-raw-image.cpp”的文件(尝试从 here 进行集成),并且在其中我创建了一个函数来使用 Java android 代码进行本地调用。

extern "C"{
void Java_com_example_ndksetup_MainActivity_testTest(JNIEnv * env, jobject ths){
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "Testing");

ScreenshotClient screenshot;
//screenshot.update();
}
}

我试图引用 ScreenshotClient 类(在同一个文件中)并创建它的一个新实例,但在构建/编译时不断出现此错误:

"undefined reference to 'android::ScreenshotClient::ScreenshotClient()' collect2: ld returned 1 exit status"

这是 ScreenshotClient 类的样子,感谢任何帮助,谢谢。

class ScreenshotClient {
/*
sp<IMemoryHeap> mHeap;
uint32_t mWidth;
uint32_t mHeight;
PixelFormat mFormat;
*/
char data[1024]; //android 4.2 embed CpuConsumer::LockedBuffer here which cause more space
public:
ScreenshotClient();

#if defined(TARGET_ICS)
// frees the previous screenshot and capture a new one
int32_t update();
#endif
#if defined(TARGET_JB)
// frees the previous screenshot and capture a new one
int32_t update(const sp<IBinder>& display);
#endif
// pixels are valid until this object is freed or
// release() or update() is called
void const* getPixels() const;

uint32_t getWidth() const;
uint32_t getHeight() const;
uint32_t getStride() const; //base + getStride()*bytesPerPixel will get start address of next row
int32_t getFormat() const;
// size of allocated memory in bytes
size_t getSize() const;
};

#if defined(TARGET_JB)
class SurfaceComposerClient {
public:
//! Get the token for the existing default displays.
//! Possible values for id are eDisplayIdMain and eDisplayIdHdmi.
static sp<IBinder> getBuiltInDisplay(int32_t id);
};
#endif

class ProcessState {
char data[1024]; //please adjust this value when you copy this definition to your real source!!!!!!!!!!!!!!!!!!!!!!!
public:
static sp<ProcessState> self();
void startThreadPool();
};

} //end of namespace android

using android::ScreenshotClient;
using android::sp;
using android::IBinder;
#if defined(TARGET_JB)
using android::SurfaceComposerClient;
#endif
using android::ProcessState;

#endif //} end of "if defined(TARGET_ICS) || defined(TARGET_JB)"

编辑:我在 extern "C"部分中将 native 函数设为静态,现在调用它时出现以下错误,但至少它现在正在编译。

06-17 16:47:09.365: E/AndroidRuntime(18566): FATAL EXCEPTION: main 06-17 16:47:09.365: E/AndroidRuntime(18566): java.lang.IllegalStateException: Could not execute method of the activity 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.view.View$1.onClick(View.java:3699) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.view.View.performClick(View.java:4223) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.view.View$PerformClick.run(View.java:17281) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.os.Handler.handleCallback(Handler.java:615) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.os.Handler.dispatchMessage(Handler.java:92) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.os.Looper.loop(Looper.java:137) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.app.ActivityThread.main(ActivityThread.java:4898) 06-17 16:47:09.365: E/AndroidRuntime(18566): at java.lang.reflect.Method.invokeNative(Native Method) 06-17 16:47:09.365: E/AndroidRuntime(18566): at java.lang.reflect.Method.invoke(Method.java:511) 06-17 16:47:09.365: E/AndroidRuntime(18566): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008) 06-17 16:47:09.365: E/AndroidRuntime(18566): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775) 06-17 16:47:09.365: E/AndroidRuntime(18566): at dalvik.system.NativeStart.main(Native Method) 06-17 16:47:09.365: E/AndroidRuntime(18566): Caused by: java.lang.reflect.InvocationTargetException 06-17 16:47:09.365: E/AndroidRuntime(18566): at java.lang.reflect.Method.invokeNative(Native Method) 06-17 16:47:09.365: E/AndroidRuntime(18566): at java.lang.reflect.Method.invoke(Method.java:511) 06-17 16:47:09.365: E/AndroidRuntime(18566): at android.view.View$1.onClick(View.java:3694) 06-17 16:47:09.365: E/AndroidRuntime(18566): ... 11 more 06-17 16:47:09.365: E/AndroidRuntime(18566): Caused by: java.lang.UnsatisfiedLinkError: Native method not found: com.example.ndksetup.MainActivity.testTest:()V 06-17 16:47:09.365: E/AndroidRuntime(18566): at com.example.ndksetup.MainActivity.testTest(Native Method) 06-17 16:47:09.365: E/AndroidRuntime(18566): at com.example.ndksetup.MainActivity.t(MainActivity.java:72) 06-17 16:47:09.365: E/AndroidRuntime(18566): ... 14 more

这是我的 Android.mk 生成文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS := -llog

LOCAL_MODULE := ndksetup
LOCAL_MODULE := libgui
LOCAL_SRC_FILES := fake_libgui.cpp
LOCAL_SRC_FILES := get-raw-image.cpp
LOCAL_SHARED_LIBRARIES += libgui

include $(BUILD_SHARED_LIBRARY)

最佳答案

第二次尝试:您不能将 JNI 方法声明为静态,因为它必须对动态加载程序“可见”。

第一次尝试:在 ICS 或更高版本上,类 ScreenshotClientlibgui.so 的一部分(早期版本在系统库中有此类称为 libsurfaceflinger_client.so) 您可以使用命令从您的设备或模拟器中提取它

adb pull /system/lib/libgui.so c:\android\libs\libgui.so

现在在您的 Android.mk 中,将 LOCAL_LDFLAGS += c:/android/libs/libgui.so 添加到您的模块。

您将看到来自 ndk-build 的警告:

Android NDK: WARNING:jni/Android.mk: non-system libraries in linker flags: c:/android/libs/libgui.so

这是在 ndk-build 中使用非公开 API 的代价。

期待 future 的问题:确保您的应用具有访问屏幕的所有相关权限。参见 How to use ScreenShotClient in my android application进行相关讨论。

更新

引用 GitHub使用假库而不是从设备中提取它们。使用 Android.mk 很容易实现这一点。得到 fake_libbinder.cppLOCAL_PATH 目录,并将以下部分添加到您的 Android.mk 中:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libibgui
LOCAL_SRC_FILES := fake_gui.cpp
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndksetup
LOCAL_SRC_FILES := get-raw-image.cpp
LOCAL_SHARED_LIBRARIES += libgui
include $(BUILD_SHARED_LIBRARY)

现在将 LOCAL_SHARED_LIBRARIES += libgui 添加到您的主模块。

对于伪造的 libbinder,您可能需要同样的东西。不过,您的应用程序将使用设备 /system/lib 中的real libbinder 和 libgui 库。不过,这取决于未更改的系统调用。

关于java - Android NDK - 在 native 函数中引用 C++ 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24273983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com