二.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}) #选择要使用

运行结果:

二.extern "C"
code:https://github.com/HumorSmith/NDKPraticle/tree/master/2_ndk_external