Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> java/android 使用swig編譯c/c++ 代碼類型轉換

java/android 使用swig編譯c/c++ 代碼類型轉換

編輯:關於Android編程

今天被同時問到java/android 使用swig編譯c/c++ 代碼類型轉換。想起找個中文版swig看一下,雖然找到了,但也是基本是英文。

中文版首頁的:http://www.swig.org/translations/chinese/index.html

中文版swig3.0文檔:http://www.swig.org/Doc3.0/SWIGDocumentation.html

我主要看了java方面的類型跟c/c++ 代碼類型轉換。

現在用幾張圖總結一下:

 

1、默認的原始類型映射

下表列出了默認從Java類型映射到C / c++。

 

\

注意,swig包裝C char類型作為一個角色。這種類型的指針和數組作為字符串包裹。簽署char類型可以使用,如果你想把字符作為有符號數,而不是一個字符。還要注意,所有常量引用原始類型被視為如果他們通過價值。

int和C段的映射適用於32位應用程序用於32位jvm。沒有完美的Java和C之間的映射為Java不支持所有的無符號C數據類型。然而,映射允許每個C的值從Java類型。
前一節中介紹了原始類型映射。類和結構體等非基本類型映射使用指針在C / c++端和存儲到一個Java長變量的指針被代理類或類型的包裝器類。這是否適用於編組為指針類型,通過引用或值。它還適用於任何未知的/不完整的類型,使用類型的包裝器類。
總之,C / c++非基本指針類型轉換為64位Java長類型,因此jlong JNI類型。Java類型是包裝類代理類或類型。
如果您使用的是64位JVM您可能必須覆蓋C長,但是可能不是C int默認映射。映射將依賴於系統,例如長需要重新映射在Unix LP64系統(64位長,指針,int 32位),但不是在微軟64位Windows將使用P64 IL32(64位指針,int,長32位)模型。這可能是自動化在未來版本的痛飲。注意,Java一次編寫到處運行理念適用於所有純Java代碼時,過渡到64位JVM。不幸的是它不會當然適用於JNI代碼。

2、Typemaps C / c++類型映射到Java類型

Java模塊主要包括中列出的常見typemaps typemaps部分。有許多額外的typemaps為使用SWIG與Java是必要的。其中最重要的實現C / c++類型映射到Java類型:

\

注意,“在”typemap執法官JNI類型“JNI”typemap舉行真正的C / c++類型相反的方向,”“typemap警察真正的C / c++類型JNI類型在“JNI”typemap舉行。非基本類型的“在”和“出”typemaps負責鑄件之間的C / c++和64位jlong類型指針。沒有便攜的方法把一個指針變成一個64位整數類型和方法swig主要是可移植的,但休息C / c++混疊的規則。總之,這些規則聲明一個指向任何類型絕不能由一個指針引用其他任何不兼容的類型。下面的代碼片段可能會幫助更好地理解混淆的規則:

 

short a;
    short* pa = 0;
    int i = 0x1234;

    a = (short)i;    /* okay */
    a = *(short*)&i; /* breaks aliasing rules */
 %typemap(in) struct Foo * %{
      $1 = *(struct Foo **)&$input; /* cast jlong into C ptr */
    %}
    %typemap(out) struct Bar * %{
      *(struct Bar **)&$result = $1; /* cast C ptr into jlong */
    %} 
    struct Bar {...};
    struct Foo {...};
    struct Bar * FooBar(struct Foo *f);

 

導致下面的代碼,打破了混疊規則:

 

 

SWIGEXPORT jlong JNICALL Java_exampleJNI_FooBar(JNIEnv *jenv, jclass jcls,
                                                jlong jarg1, jobject jarg1_) {
  jlong jresult = 0 ;
  struct Foo *arg1 = (struct Foo *) 0 ;
  struct Bar *result = 0 ;
  
  (void)jenv;
  (void)jcls;
  (void)jarg1_;
  arg1 = *(struct Foo **)&jarg1; 
  result = (struct Bar *)FooBar(arg1);
  *(struct Bar **)&jresult = result; 
  return jresult;
}

 

3、默認的原始類型映射

下表列出了從C / c++默認類型映射。這個表格會告訴你為一個函數類型去期待它使用一個給定的C / c++類型。
\

 

注意,swig包裝C char類型作為一個角色。這種類型的指針和數組作為字符串包裹。簽署char類型可以使用,如果你想把字符作為有符號數,而不是一個字符。還要注意,所有常量引用原始類型被視為如果他們通過價值。
這些類型映射定義的“gotype typemap”。你可能改變typemap,或添加新值,控制C / c++類型是如何映射到類型。

由於輸出參數的處理方式的局限性在swig,一個函數與輸出參數將不會有多個返回值。相反,您必須通過一個指針到c++函數來告訴它在哪裡存儲輸出值。在去,你供應一片地方的輸出參數。

例如,假設您想將modf C數學庫中()函數將x分為整體和部分部件(並返回整數部分的參數):

 

double modf(double x, double *ip);
您可以使用%申請指令:
%include 
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
%include 
%apply signed char *OUTPUT {char *output};
void f(char *output);

 

4、包裝C數組與Java數組

swig可以陣列封裝在一個更自然比默認使用arrays_java Java的方式。我庫文件。讓我們考慮一個例子:

 

 

%include "arrays_java.i";
int array[4];
void populate(int x[]) {
    int i;
    for (i=0; i<4; i++)
        x[i] = 100 + i;
}
這些一維數組可以用作如果他們Java數組:

 

 

int[] array = new int[4];
example.populate(array);

System.out.print("array: ");
for (int i=0; i<array.length; for="" global_array="example.getArray();" i="0;" int="" nglobal_array:="" pre="">
java數組總是以引用的方式傳遞,因此一個函數對數組的任何更改將被調用的函數。這裡是輸出後運行這段代碼:

array: 100 101 102 103
global_array: 100 101 102 103

5、STL / c++庫

圖書館模塊在本節中提供的部分標准c++庫包括STL。swig對STL是一項持續的努力的支持。支持非常全面的一些語言模塊,但使用的一些較小的模塊沒有那麼多庫編寫的代碼。 下面的表顯示了支持c++類和等效痛飲c++庫接口庫文件。

\

%module example
%include "std_string.i"

%apply const std::string& {std::string* foo};

struct my_struct
{
  std::string foo;
};
\

說了那麼多,文檔看了那麼多,都是類型的轉換。

還有一個很重要的特點就是。返回值時候可以以多參數的形式返回。

		double[] dSource1 = new double[1];
		double[] dSource2 = new double[1];
		double[] dSource3 = new double[1];
		double[] deditViewInputData = new double[3];
		SourceCoord.XYZ_2(deditViewInputData[0],deditViewInputData[1], deditViewInputData[2],
					dSource1, dSource2, dSource3);
上面是java代碼,那麼計算出來的值是放在三個double數組裡面。

最後附上一個標准c++頭文件

#ifndef _2013_H_
#define _2013_H_
#include 
#include 
#include 
#ifdef SWIG
%include "std_string.i"
%include "typemaps.i"
%include "arrays_java.i"
%apply signed char[] {char*}
#endif // SWIG
class 2013
{
public:
    2013(void);
    ~2013(void);
public:
    int  Auth(const std::string& m_N, const std::string& m_ID, const std::string& m_CODE, char *m_DATA);
    int  NetAuth(const std::string& m_JSH,const std::string& m_KEY,const std::string& m_PID,const std::string& m_Code,char *Return_Mes);
    void EncodeBase64(const std::string& Src,int Src_len,char *base64code);
private:
    void EncodeBase64(char *Src,int Src_len,char *base64code);
    void DecodeBase64(const char *szCoded, char *Des,int &Des_len);
    int  CheckkCRC16( unsigned  char *data, int Len);
};
#endif
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved