65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 CLE 从 Java Android 调用 C/C++

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2012 年 3 月 5 日

CPOL

1分钟阅读

viewsIcon

13737

如何使用 CLE 从 Java Android 调用 C/C++

存在大量的 C/C++ 语言编写的资源。但在 Android 平台上,Java 是主要的语言。开发者必须使用 JNI 来封装 C/C++ 代码的接口。JNI 适用于简单的情况。对于更复杂的应用,程序员需要维护 C++ 对象到 Java 对象的引用,处理从 C/C++ 到 Java 的回调函数等,这些并不容易。使用 CLE,这些工作将由 CLE 完成,程序员只需要专注于特定的功能。

对于 Java 调用 C/C++ 使用 CLE,方法不像 Java 调用脚本那样直接,例如 lua、python 等。因为脚本语言都有反射机制。我们可以动态地获取函数和属性定义。但对于 C/C++,没有类似的机制。源代码中的所有定义都将被编译成二进制代码。因此,在使用 CLE 之前,我们需要先描述函数和属性。

描述对象属性和函数有两种方法。

第一种方法,使用 CLE 的接口函数

    void *AtomicClass,*Add_AtomicFunction,*Print_AtomicFunction;
    AtomicClass = SRPInterface ->CreateAtomicObjectSimple(
        "TestItem","TestClass","VS_INT32 CValue",NULL,NULL);
    Add_AtomicFunction = SRPInterface ->CreateAtomicFunctionSimple(
        AtomicClass,"CAdd",
        "VS_INT32 CAdd(VS_INT32 x,VS_INT32 y);",NULL,NULL,VS_FALSE,VS_FALSE);
    Print_AtomicFunction = SRPInterface ->CreateAtomicFunctionSimple(
        AtomicClass,"CPrint",
        "void CPrint(VS_INT32 x,VS_INT32 y);",NULL,NULL,VS_FALSE,VS_FALSE);

第二种方法,使用 XML 字符串生成对象的属性和函数

    void *AtomicClass,*Add_AtomicFunction,*Print_AtomicFunction;
    class ClassOfSRPSXMLInterface *SXMLInterface;
    SXMLInterface = BasicSRPInterface -> GetSXMLInterface();
    
    SXMLInterface -> LoadFromBuf(

"   <?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"    
"   <sysrootitem>\n"
"        <TestItem>\n"
"            <object>\n"
"                <TestClass ID=\"ed51e615-e548-442e-8802-a99b2fa8fe15\">\n"
"                    <attribute>\n"
"                        <CValue Type=\"VS_INT32\" />\n"
"                    </attribute>\n"
"                    <function>\n"
"                        <CAdd ID=\"f402fd47-8bea-4136-b7f7-45bb7fb51b14\">\n"
"                            <input Name=\"x\" Type=\"VS_INT32\" />\n"
"                            <input Name=\"y\" Type=\"VS_INT32\" />\n"
"                            <output Type=\"VS_INT32\" />\n"
"                        </CAdd>\n"
"                        <CPrint ID=\"da44c24e-f20a-46e3-8d37-49c3b90c6c05\">\n"
"                            <input Name=\"x\" Type=\"VS_INT32\" />\n"
"                            <input Name=\"y\" Type=\"VS_INT32\" />\n"
"                        </CPrint>\n"
"                    </function>\n"
"                </TestClass>\n"
"            </object>\n"
"        </TestItem>\n"
"   </sysrootitem>\n"
    ,NULL);
    
    SRPInterface -> XmlToSysRootItem(SXMLInterface,NULL,"",NULL,0);
    
    AtomicClass = SRPInterface ->GetAtomicObject
    (_UUIDPTR("ed51e615-e548-442e-8802-a99b2fa8fe15"));
    Add_AtomicFunction = SRPInterface ->GetAtomicFunction
    (_UUIDPTR("f402fd47-8bea-4136-b7f7-45bb7fb51b14"));
    Print_AtomicFunction = SRPInterface ->GetAtomicFunction
    (_UUIDPTR("da44c24e-f20a-46e3-8d37-49c3b90c6c05"));

完成对象属性和函数的描述后,我们可以附加函数体地址

    //---Set Function Address    
    SRPInterface -&gt; SetAtomicFunction(Add_AtomicFunction,(void *)CAdd);    
    SRPInterface -&gt; SetAtomicFunction(Print_AtomicFunction,(void *)CPrint);

此时,这些函数和属性可以从 Java 访问。

Java 代码

StarObjectClass a = Service._GetObject("TestClass")._New();
a._Call("CAdd",12,34));

C/C++ 回调到 Java

java call back function:
StarObjectClass a = Service._GetObject("TestClass")._New()._Assign(new StarObjectClass(){
		    public int JavaAdd(StarObjectClass self,int x,int y){
		        return x+y;
		    }
		 });

C 代码

    VS_INT32 ScriptStack;
    
    ScriptStack = SRPInterface -> ScriptGetStack();     //----save script stack
    SRPInterface -> Print( "Function result from java %d",
             SRPInterface -> ScriptCall
             (Object,NULL,"JavaAdd","(ii)i)",x,y) );
    SRPInterface -> ScriptSetStack(ScriptStack);

源代码(将 CLE 集成到您的项目中)

  1. http://code.google.com/p/cle-for-android 下载 devfiles,然后打开 Eclipse
  2. 创建一个 Android 项目。
  3. 将 CLE jar 添加到项目,如下所示

C++ 代码

#include "vsopenapi.h"
class ClassOfSRPInterface *SRPInterface;
struct StructOfTestClass{
    VS_INT32 CValue;
};    
static VS_INT32 CAdd(void *Object,VS_INT32 x,VS_INT32 y)
{
    struct StructOfTestClass *TestClass;
    
    TestClass = (struct StructOfTestClass *)Object;
    TestClass -> CValue = 200;
    SRPInterface -> Print("Call c function...");
    return x+y;    
}
static void CPrint(void *Object,VS_INT32 x,VS_INT32 y)
{
    VS_INT32 ScriptStack;
    
    ScriptStack = SRPInterface -> ScriptGetStack();     //----save script stack
    SRPInterface -> Print( "Value defined in java is %d",SRPInterface -> 
    ScriptGetInt(Object,"JavaValue") );
    SRPInterface -> Print( "Function result from java %d",
                    SRPInterface -> ScriptCall(Object,NULL,"JavaAdd","(ii)i)",x,y) );
    SRPInterface -> ScriptSetStack(ScriptStack);     //----restore script stack
}
VS_BOOL StarCoreService_Init(class ClassOfStarCore *starcore)
{
    void *AtomicClass,*Add_AtomicFunction,*Print_AtomicFunction;
    class ClassOfBasicSRPInterface *BasicSRPInterface;
    
    //--init star core
    BasicSRPInterface = starcore ->GetBasicInterface();    
    SRPInterface = BasicSRPInterface ->GetSRPInterface
    (BasicSRPInterface->QueryActiveService(NULL),"","");
    
    //---Create Atomic Class, for define function,  
    AtomicClass = SRPInterface ->CreateAtomicObjectSimple
    ("TestItem","TestClass","VS_INT32 CValue",NULL,NULL);
    Add_AtomicFunction = SRPInterface ->CreateAtomicFunctionSimple
    (AtomicClass,"CAdd","VS_INT32 CAdd(VS_INT32 x,VS_INT32 y);",
    NULL,NULL,VS_FALSE,VS_FALSE);
    Print_AtomicFunction = SRPInterface ->CreateAtomicFunctionSimple
    (AtomicClass,"CPrint","void CPrint(VS_INT32 x,VS_INT32 y);",
    NULL,NULL,VS_FALSE,VS_FALSE);    
    //---Set Function Address
    SRPInterface -> SetAtomicFunction(Add_AtomicFunction,(void *)CAdd);
    SRPInterface -> SetAtomicFunction(Print_AtomicFunction,(void *)CPrint);
    return VS_TRUE;
}
void StarCoreService_Term(class ClassOfStarCore *starcore)
{
    SRPInterface -> Release();
    return;
}

使用 NDK 将代码编译成共享库,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 := AddFunction.cpp
LOCAL_SRC_FILES := ${MODULE_CXXSRCS}
LOCAL_LDLIBS := ../../cle_files/libs/armeabi/libstarlib.a
LOCAL_MODULE  := AddFunction
include $(BUILD_SHARED_LIBRARY)

Java 代码

package com.cle.cfromjava;

import android.app.Activity;
import android.os.Bundle;

import com.srplab.www.starcore.*;
import com.srplab.netinst.*;

public class CfromjavaActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //--init CLE
        starcore_net_inst.InstallZipFile
        (this,"libstarcore.so",
        "http://www.srplab.com/android/starcore_armeabi_r3.zip", 
        "/data/data/com.cle.cfromjava/files");
        StarCoreFactoryPath.StarCoreShareLibraryPath = 
        "/data/data/com.cle.cfromjava/files";
        StarCoreFactoryPath.StarCoreOperationPath = 
        "/data/data/com.cle.cfromjava/files";                
        
		 StarCoreFactory starcore= StarCoreFactory.GetFactory();
		 StarServiceClass Service=starcore._InitSimple
		 ("test","123",0,0);
		 Service._CheckPassword(false);
      
        Service._DoFile
        ("","/data/data/com.cle.cfromjava/lib/libAddFunction.so","");
        
		 StarObjectClass a = Service._GetObject
		 ("TestClass")._New()._Assign(new StarObjectClass(){
		    public int JavaAdd(StarObjectClass self,int x,int y){
		        System.out.println("Call java function...");
		        return x+y;
		    }
		 });
        a._Set("JavaValue",100);
        System.out.println(a._Call("CAdd",12,34));                   
        System.out.println(a._Get("CValue"));						
         a._Call("CPrint",56,78);   
        
        starcore._ModuleExit();
    }
}
© . All rights reserved.