(转自:http://blog.csdn.net/srplab1/article/details/7617963)

在某些情况下,比如原来与很多c/c++的代码, 可能希望采用c/c++编写android应用程序.在这种情况下,一般使用NDK.但是由于android直提供了java接口,因此不能够直接调用 android中的各种对象或者部件. 如何直接使用c/c++开发android应用? 可以使用cle和wrapandroid项目作为中间件. CLE项目提供了多种语言的通用接口,其中就包含对c/c++的支持.

本文简单介绍了如何使用CLE和wrapandroid编写GUI应用程序。CLE可以作为多
种语言的通用平台,支持java, python,c/c++,lua,
等,且可以扩展至其它多种语言,也可以自定义语言。在CLE中,对象作为1个基本的操作元素。对象对外提供了统一的接口,可以通过这些接口,调用对象的函
数,重载对象的函数,捕获对象的事件.


Wrapandroid将android类封装成为CLE对象,从而可以使程序员在c/c++中使用android的类。一般有以下几个步骤:
1.    使用CLE接口函数MallocObjectL创建android类的实例对象
2.    使用ScriptCall接口函数调用对象的方法
3.   使用CreateOvlFunction重载对象的函数

4.    使用RegEventFunction注册对象的事件处理函数

步骤1: 准备环境

a: CLE可以在应用启动的时候自动安装,只需要在工程中包含starcore_android_r6.jar,该文件在starcore_devfiles_r6.zip压缩包中, 可以从链接:http://code.google.com/p/cle-for-android 下载。

b: Wrapandroid是一个jar库,可以从http:/code.google.com/p/wrapandroid-for-multilaguage/download/wrapandroid_devfiles_0_8_5.rar下载。

步骤2 : 开始编程

开发工具使用eclipse和NDK. 这两个如何安装和使用,请参阅相关的文档.

 
a. 打开eclipse, 创建一个新工程,名字为“introduction”

b. cle可以在应用启动的时候从网络下载,此时需要在工程中增加以下许可:

    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

c. 将java库文件starcore_android_r6.jar和wrapandroid.jar拷贝到工程目录,并加入到工程中:

d. 编辑IntroductionActivity.java,如下修改,装载共享库

import com.srplab.wrapandroid.*;

public class IntroductionActivity extends WrapAndroidActivity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        StarActivity._Call("DoFile","","/data/data/"+getPackageName()+"/lib/libCode.so");

    }

}

e cle也可以打包到工程中,此时需要将CLE的共享库文件放到工程目录中,如下:

同时,将下载标志设置为false

public class IntroductionActivity extends WrapAndroidActivity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        DownloadFromNetFlag = false;

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        StarActivity._Call("DoFile","","/data/data/"+getPackageName()+"/lib/libCode.so");

    }

}

f. 编辑布局文件:main.xml.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/widget73"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    <TextView

        android:id="@+id/widget45"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="@string/hello" />

    <Button

        android:id="@+id/widget74"

        android:layout_width="220dp"

        android:layout_height="48dp"

        android:text="thank for your use"

        android:typeface="serif"

        android:textStyle="bold"

        android:textColor="#ffff0000"

        android:layout_x="284dp"

        android:layout_y="220dp"

        android:textSize="16dp"

    />

</LinearLayout>

 
g. 在工程目录下,创建jni目录, 将wrap android和cle头文件拷贝到该目录下. 创建新文件code.cpp. and Android.mk, 编辑Android.mk:

 
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Here we give our module name and sourcefile(s)

LOCAL_CFLAGS += -Wno-write-strings -DENV_ANDROID

LOCAL_CPPFLAGS += -Wno-write-strings -fexceptions -DENV_ANDROID

LOCAL_LDFLAGS += -Wno-write-strings -DENV_ANDROID

LOCAL_C_INCLUDES += cle_files/include

#--------source file

MODULE_CXXSRCS := Code.cpp SRPWrapAndroidEngine_UUIDDef.cpp

LOCAL_SRC_FILES := ${MODULE_CXXSRCS}

LOCAL_LDLIBS := cle_files/libs/armeabi/libstarlib.a

LOCAL_MODULE  := Code

include $(BUILD_SHARED_LIBRARY)

#------------------------

include $(CLEAR_VARS)

LOCAL_SRC_FILES := cle_files/so/armeabi/libstarcore.so

LOCAL_MODULE  := starcore

include $(PREBUILT_SHARED_LIBRARY)

#------------------------

include $(CLEAR_VARS)

LOCAL_SRC_FILES := cle_files/so/armeabi/libstar_java.so

LOCAL_MODULE  := star_java

include $(PREBUILT_SHARED_LIBRARY)

步骤3. Code.cpp

采用原生代码编写android应用,需要将其编译成为共享库。共享库输出两个接口函数:

VS_BOOL StarCoreService_Init(class ClassOfStarCore *starcore)

void StarCoreService_Term(class ClassOfStarCore *starcore)

 
第一个函数在共享库装载的时候调用,可以进行一些初始化工作;第二个函数在共享库卸载的时候调用

 
代码如下:
 
//--wrap android头文件
#include "SRPWrapAndroidEngine_VSClass.h"

 
//--服务接口,其它所有函数都通过该接口调用.

static class ClassOfSRPInterface *SRPInterface;

 
//--android Activity对象,由java代码创建.

static void *StarActivity;

 
//--按钮的事件函数。 事件函数的处理原型都相同.

static VS_INT32 MyButton_onClick(VS_ULONG FunctionChoice,void *EventPara)

{

    //--当事件被触发时,显示一些信息.

        //--创建toast对象。

    void *toast = SRPInterface->MallocObjectL(&VSOBJID_ToastClass,0,NULL);

        //--调用toast的函数“makeText”, (si) 为输入参数的类型,详细解释需要参阅CLE文档.

    SRPInterface -> ScriptCall(toast,NULL,"makeText","(si)","Button is click", 0);

        //--调用toast的函数“show”

    SRPInterface -> ScriptCall(toast,NULL,"show","()");

    return 0;

}

static VS_INT32 MyButton1_onClick(VS_ULONG FunctionChoice,void *EventPara)

{

    void *toast = SRPInterface->MallocObjectL(&VSOBJID_ToastClass,0,NULL);

    SRPInterface -> ScriptCall(toast,NULL,"makeText","(si)","Button is click", 0);

    SRPInterface -> ScriptCall(toast,NULL,"show","()");

        return 0;

}

//--共享库的初始化函数

VS_BOOL StarCoreService_Init(class ClassOfStarCore *starcore)

{

    class ClassOfBasicSRPInterface *BasicSRPInterface;

    //--获取基本服务接口

    BasicSRPInterface = starcore ->GetBasicInterface();

        //---获取当前的服务接口,服务由java代码创建

    SRPInterface = BasicSRPInterface ->GetSRPInterface(BasicSRPInterface->QueryActiveService(NULL),"","");

    void *ActivityClass;

        //---获取被封装的acvitity类

    ActivityClass = SRPInterface -> GetObjectEx(NULL,"ActivityClass");

        //--调用getCurrent function获取当前的activity, 由java代码创建. ()O 表示返回值为一个cle对象

    StarActivity = (void *)SRPInterface -> ScriptCall(ActivityClass,NULL,"getCurrent","()O");

        //--打印一些信息,打印的信息会显示到logcat中.

    SRPInterface -> Print("Get Main Activity = %s", SRPInterface -> GetName(StarActivity));    
 
    //--调用activity的函数getResource获取布局中定义的资源的ID. 输入参数为字符串,输出为整数,使用标记为(s)I.

int widget45 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget45");

        //--调用findViewById函数获取textview. 该函数与android的函数原型略为不同,输入参数中增加的类的名称。
        void *MyText = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)o","TextViewClass",widget45);
        //--调用textview的函数setText。

        SRPInterface -> ScriptCall(MyText,NULL,"setText","(s)","TextViewClass","from layout");

        int widget74 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget74");

        //--调用findViewById获取按钮对象

        void *MyButton = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)o","ButtonClass",widget74);

        //--调用按钮对象的setText.

        SRPInterface -> ScriptCall(MyButton,NULL,"setText","(s)","click me");

        //--调用按钮对象的函数setOnClickListener.

        SRPInterface -> ScriptCall(MyButton,NULL,"setOnClickListener","()");

        //--注册事件的处理函数

        SRPInterface -> RegEventFunction(MyButton,&VSOUTEVENTID_ViewClass_onClick,MyButton,(void *)MyButton_onClick,0);

        int widget73 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget73");

        //--调用findViewById获取LinearLayout.

    void *MyLinearLayout = (void *)SRPInterface ->
ScriptCall(StarActivity,NULL,"findViewById","(si)o","LinearLayoutClass",widget73);

        //--动态创建按钮对象,是linearlayout的子对象

    void *MyDynaButton =
SRPInterface->MallocObject(MyLinearLayout,VSATTRINDEX_VIEWGROUPCLASS_VIEWQUEUE,&VSOBJID_ButtonClass,0,NULL);

        SRPInterface -> ScriptCall(MyDynaButton,NULL,"setText","(s)","created dynamically");

        SRPInterface -> ScriptCall(MyDynaButton,NULL,"setOnClickListener","()");

        SRPInterface ->
RegEventFunction(MyDynaButton,&VSOUTEVENTID_ViewClass_onClick,MyDynaButton,(void
*)MyButton1_onClick,0);

        //--设置布局参数

        SRPInterface -> ScriptCall(MyDynaButton,NULL,"setLinearLayoutParams","(ii)",100,50);

    return VS_TRUE;

}

void StarCoreService_Term(class ClassOfStarCore *starcore)

{

    SRPInterface -> Release();

    return;

}

Step 4. 使用ndk编译成为共享库

运行结果

例子下载:

http://wrapandroid-for-multilanguage.googlecode.com/svn/wiki/examples/c_introduction.zip

C/C++开发android应用的更多相关文章

  1. Xamarin开发Android应用打包apk

    Visual Studio中用Xamarin开发Android应用,生成apk文件有3种方法 1.debug时,代码目录下bin\Debug中会自动生成调试用***-Signed.apk文件,但是文件 ...

  2. visual studio 2015 开发android

    转载请注明: http://www.cnblogs.com/sunyl/p/5493249.html http://www.cnblogs.com/sunyl/ 最近有不少新闻, 甲骨文向谷歌索赔93 ...

  3. 在vs2012中用C#开发Android应用Xamarin环境搭建

    Xamarin是Mono创始人Miguel de Icaza创建的公司,旨在让开发者可以用C#编写iOS, Android, Mac应用程序,也就是跨平台移动开发. 简介 Xamarin是基于Mono ...

  4. 用Kotlin开发Android应用(II):创建新项目

    这是关于Kotlin的第二篇.各位高手发现问题,请继续“拍砖”. 原文标题:Kotlin for Android(II): Create a new project 原文链接:http://anton ...

  5. 用Kotlin开发Android应用(I):介绍

    关于Kotlin,网上已有一些介绍的文章,包括Antonio Leiva的这组blog翻译稿.不过,我还是想跟进它们.翻译它们,以锻炼自己的英文翻译.各位高手发现问题,请及时“拍砖”. 原文题目:Ko ...

  6. Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)

    Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...

  7. Xamarin Mono For Android 4.6.07004 完整离线安装破解版(C#开发Android、IOS工具)

      Xamarin是由Miguel de Icaza成立的一家新的独立公司,目的是给Mono一个继续奋斗的机会.Mono for Android (原名:MonoDroid)可以让开发人员使用 Mic ...

  8. 简单谈谈eclipse下搭建PhoneGap环境来开发Android程序 - linux86(转)

    原来在逛园子的时候一不小心发现了一个新概念“PhoneGap”简称PG,我一直都喜欢追逐新事物,自然就产生了好奇心.于是乎我就在百度上面Google了一下PhoneGap是什么东西.简单的说就是用另一 ...

  9. Qt for Android开发Android应用时的各种错误汇总(此片博文不成熟,请大家略过)

    “Qt for Android真的很脆弱,项目能跑起来靠的是奇迹,跑不起来,各种报错才是正常...” 问题一:Qt for Android编译不过:make (e=2): 系统找不到指定的文件. 之前 ...

  10. Xamarin Mono 环境搭建(使用Visual Studio 2013 开发android 和 ios )

    本文主要介绍Xamarin结合VS2013来开发Android应用程序,主要会介绍Mono和Xamarin的关系,以及整个搭建环境的过程. 一.Mono和Xamarin介绍 1.Mono简介 Mono ...

随机推荐

  1. filebeat 简介安装

    Filebeat is a lightweight shipper for forwarding and centralizing log data. Installed as an agent on ...

  2. linux c编程:互斥锁条件变量

    条件变量:等待与信号发送 使用互斥锁虽然可以解决一些资源竞争的问题,但互斥锁只有两种状态(加锁和解锁),这限制了互斥锁的用途. 条件变量(条件锁)也可以解决线程同步和共享资源访问的问题,条件变量是对互 ...

  3. java-序列化-001-原生介绍

    一.什么是对象序列化 java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长.但在现实应用中, ...

  4. 你真的会用Retrofit2吗?Retrofit2完全教程

    本文注目录: Retrofit入门 Retrofit注解详解 Gson与Converter RxJava与CallAdapter 自定义Converter 自定义CallAdapter 其它说明 前言 ...

  5. 海量数据处理之Bloom Filter详解

    前言 :  即可能误判    不会漏判   一.什么是Bloom Filter     Bloom Filter是一种空间效率很高的随机数据结构,它的原理是,当一个元素被加入集合时,通过K个Hash函 ...

  6. for迭代序列的三种方式

    while循环是条件性的,for循环是迭代性的. for循环会访问所有迭代对象中的所有元素,并在所有条目都结束后结束循环. for循环迭代序列有三种基本的方式,分别是通过序列项迭代.通过索引迭代.通过 ...

  7. python全栈开发从入门到放弃之字符串的应用

    1.strip strip 脱去(...的)衣服 去掉左右两边的空白msg=' hellprint(msg) 1 print(msg.strip()) #去掉左右两边的空白 2 3 hello 4 h ...

  8. Web框架简介

    Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  9. LVS管理工具--ipvsadm

    一. ipvsadm工具介绍 从2.4版本开始,linux内核默认支持LVS.要使用LVS的能力,只需安装一个LVS的管理工具:ipvsadm. LVS的结构主要分为两部分: 工作在内核空间的IPVS ...

  10. [pixhawk笔记]4-如何写一个简单的应用程序

    本文主要内容来自于:https://dev.px4.io/en/tutorials/tutorial_hello_sky.html,并对文档中的部分问题进行更正. 本文假设已经建立好开发环境并能正确编 ...