二.extern "C"
extern关键字
xtern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定
一.extern "C"的作用
当它与"C"
一起连用时,如:extern "C" void fun(int a, int b)
;则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是[email protected]_int_int#%$也可能是别的,但是函数里面的方法调用还是以C++的方式来调用
二.extern "C"的使用
首先看Hello.h
//防止重复编译的头
#ifndef PRACTICLE_HELLO_H
#define PRACTICLE_HELLO_H
#include <android/log.h>
#include <jni.h>
//文件判断宏定义开头,如果是CPP文件,加入 extern "C" {
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL
Java_com_example_a2_1opencv_1gray_MainActivity_getHello(JNIEnv *env, jobject instance);
//文件判断宏定义结尾,如果是CPP文件,加入 } 结尾,和前面的 extern "C" { 对应起来
#ifdef __cplusplus
}
#endif
//防止重复编译的头结束标识
#endif //PRACTICLE_HELLO_H
再看Hello.cpp
#include "Hello.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
用C语言格式
return (*env)->NewStringUTF(env, "Hello JNI !");
C++格式
return env->NewStringUTF((char *)"Hello JNI !");
查看源码发现,这两个对象不是一个类型,只是名字一样
#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif
**/
JNIEXPORT jstring JNICALL
Java_com_example_a2_1opencv_1gray_MainActivity_getHello(JNIEnv *env, jobject instance) {
return env->NewStringUTF((char *) " Hello extern c !");
}
#ifdef __cplusplus
}
#endif
CMakeLists.txt
# 指定cmke版本
cmake_minimum_required(VERSION 3.4.1)
add_definitions(-std=c++11)
add_library(native-lib
SHARED
src/main/cpp/Hello.cpp) #添加.c源文件
include_directories(src/main/cpp/include) #添加头文件的位置
target_link_libraries(native-lib
${log-lib}) #选择要使用
运行结果:
code:https://github.com/HumorSmith/NDKPraticle/tree/master/2_ndk_external