2011-06-21 37 views
34

Tất cả các mẫu ndk chỉ sử dụng các hàm C cơ bản được khai báo là extern trong phần đầu và được định nghĩa trong tệp cpp. Sau đó, sau khi bao gồm các tập tin tiêu đề trong tập tin C có chứa gọi lại jni, mọi thứ hoạt động tốt.Sử dụng C++ với Android ndk/jni

Có thể sử dụng các lớp C++ với android ndk không? Ứng dụng của tôi sẽ không phải là một hoạt động gốc, nó vẫn sẽ có một phần java quan trọng nhưng nó sẽ gọi mã C bản địa để tính toán CPU chuyên sâu (đã được viết bằng C++, với các lớp và các công cụ C++ khác).

Đây là của tôi hello-thế giới như strcuture cho bây giờ:

File "first.h"

#ifndef FIRST_H 
#define FIRST_H 

class Test 
{}; 

#endif /* FIRST_H */ 

File "second.cpp"

#include <jni.h> 
#include "first.h" 

#ifdef __cplusplus 
extern "C" { 
#endif 

jint Java_com_example_twolibs_TwoLibs_add(JNIEnv* env, 
             jobject this, 
             jint  x, 
             jint  y) 
{ 
    Test t; 
    return 0; 
} 

#ifdef __cplusplus 
} 
#endif 

Và cuối cùng Android.mk

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

LOCAL_MODULE := libtwolib-second 
LOCAL_SRC_FILES := second.cpp 

include $(BUILD_SHARED_LIBRARY) 

Prett y cơ bản nhưng điều đó không biên dịch. Quay second.cpp trong một tệp .c làm tăng lỗi khi đưa vào tệp tiêu đề, tôi đoán điều này là do nó không phải là tệp C++.

error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test' 

Làm cho nó cpp tăng các lỗi sau:

make: *** No rule to make target `/cygdrive/c/android-ndk-r5c/samples/twolibs/jni/second.c', needed by `/cygdrive/c/android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second/second.o'. Stop. 

Bất kỳ ý tưởng làm thế nào tôi có thể làm điều đó biên dịch?

Cảm ơn

Trả lời

15

Bạn có thể sử dụng C++ với NDK, nhưng tệp có mã C++ phải có phần mở rộng .cpp.

Từ ANDROID-MK.html:

Note that the default extension for C++ source files is '.cpp'. It is however possible to specify a different one by defining the variable LOCAL_CPP_EXTENSION. Don't forget the initial dot (i.e. '.cxx' will work, but not 'cxx').

+0

Có vẻ như mã C gọi lại (tệp chứa các cuộc gọi như Java_com_example_twolibs_TwoLibs_add được gọi từ phía java) phải nằm trong tệp .c (không phải .cpp). Nếu không nó không biên dịch trên máy tính của tôi. Vì vậy, khi tôi cố gắng bao gồm một tập tin tiêu đề có chứa một tuyên bố lớp học, cùng một lỗi đi lên. – user745189

+1

Turing mọi thứ vào tập tin .cpp cho phép tôi thực hiện: *** Không có quy tắc nào để tạo lỗi mục tiêu có nghĩa là tệp tạo tệp không thể tìm thấy tệp nguồn ... nhưng nếu tôi chuyển chúng thành tệp .c thì đây không phải là một vấn đề đường dẫn tôi đoán – user745189

+0

Nó phải biên dịch, nhưng bạn cần thêm 'bên ngoài" C "' vào tất cả các hàm JNI. Bạn đã thay đổi phần mở rộng tập tin nguồn trong makefile chưa? – Michael

3

Bạn sẽ phải biên dịch lại tất cả các thư viện gốc dành riêng cho Android. Bạn cần mã nguồn cho tất cả lib gốc của bên thứ 3 mà bạn dự định sử dụng đơn giản vì thông thường khi biên dịch và liên kết các thư viện này bên ngoài Android, chúng được liên kết với glibc nhưng tiếc là Android không sử dụng glibc do sự cố và sự cố hiệu suất. Android sử dụng phiên bản được tưới nước của glibc được gọi là libc. Nó có tên biểu tượng phù hợp với glibc cho hầu hết các chức năng thông thường. Nhưng theo như tôi biết libc không có một số chức năng liên quan đến strings và nó chắc chắn không có một số hỗ trợ posix. Nếu thư viện gốc của bạn đang sử dụng bất kỳ chức năng không được chấp nhận nào, bạn sẽ phải tìm giải pháp thay thế cho những người đó bằng cách sử dụng chức năng thay thế được hỗ trợ bởi libc và mã hóa lib của bạn cho phù hợp.

Ngoài ra, khi bạn đúng, bạn đã chỉ ra rằng bạn sẽ phải sử dụng NDK để giao tiếp Java (ứng dụng Android/fwk) với thế giới tự nhiên (C++).

Mặc dù điều này nghe có vẻ khá đơn giản trong trải nghiệm biên soạn thư viện gốc trên Android (Android porting) có truyền thống rất tốn thời gian mà không đảm bảo thành công.

+0

Cảm ơn câu trả lời của bạn. Trên thực tế, tôi thậm chí không thể bắt đầu chuyển sang libs bên thứ 3 của mình vì tôi thậm chí không thể có được một bài kiểm tra đơn giản giống như thế giới để biên dịch ngay khi tôi sử dụng các lớp trong đó. Bước đầu tiên là tạo một vùng gần trống lớp thử nghiệm C++ bản địa và sử dụng nó trong tệp tin gọi lại Jni của tôi. Chỉ để xem liệu biên dịch đó. – user745189

0

error: expected '=', ',', ';', 'asm' or '__ attribute __' before 'class'

trường hợp cổ điển của thiếu ';' trước từ khóa lớp học?Hãy tưởng tượng

int functionname(int p) 
class X { } ; 

Điều này có thể dẫn đến thông điệp trình biên dịch của bạn khá dễ dàng. Một yếu tố phức tạp thường là khi nó thực sự trông như

#include "someheader.h" 
class X { } ; 

và có sai số trong việc kê khai cuối cùng bên someheader.h/hoặc bất kỳ tập tin đệ quy bao gồm /;)

+0

Đó là những gì tôi nghĩ lúc đầu nhưng tôi đã kiểm tra và đây không phải là lỗi cú pháp – user745189

1

Về lỗi biên dịch của bạn, có vẻ như bạn đầu tiên được gọi là "second.c" và sau đó đổi tên thành "second.cpp" nhưng các tệp đối tượng vẫn có tên "second.c" trong chúng nên trước khi bạn biên dịch (bdk-build), bạn cần xóa * .o và * .d tệp trong/cygdrive/c/android-ndk-r5c/mẫu/hai thư mục/obj/local/armeabi/objs/twolib-second/directory

0

ndk-build clean 

sau khi bạn sửa đổi sai Android.mk, nếu không công trình có thể tiếp tục bị lỗi ngay cả khi bạn đã sửa cấu hình.

Tôi nghĩ rằng đây là ý nghĩa của OP có nghĩa là on this comment.

0

Chỉnh sửa Android.mk

Sửa đổi các trường hợp LOCAL_SRC_FILES và xóa ./ khỏi phần bắt đầu của mỗi dòng.

Các vấn đề liên quan