2015年2月17日 星期二

使用eclipse 編譯json函式庫

C語言

參考 https://linuxprograms.wordpress.com/2010/05/20/json-c-libjson-tutorial/

使用終端機


  1. 首先安裝需要的package
  2. 利用以下的測試程式來測試環境
#include <json/json.h>
#include <stdio.h>

int main() {
 char * string = "{"name" : "joys of programming"}";
 json_object * jobj = json_tokener_parse(string);
 enum json_type type = json_object_get_type(jobj);
 printf("type: ",type);
 switch (type) {
 case json_type_null: printf("json_type_nulln");
 break;
 case json_type_boolean: printf("json_type_booleann");
 break;
 case json_type_double: printf("json_type_doublen");
 break;
 case json_type_int: printf("json_type_intn");
 break;
 case json_type_object: printf("json_type_objectn");
 break;
 case json_type_array: printf("json_type_arrayn");
 break;
 case json_type_string: printf("json_type_stringn");
 break;
 }
}
     3.  編譯   gcc json_type.c -l json

使用Eclipse

  1. 建立一個C專案,將上列測試程式加到專案中。
  2. 點專案再按右鍵->Properties->C/C++ General->Paths and Symols ->Includes加入/usr/include/json
  3. 接下來選C/C++ Build->Settings->GCC C++ Linker->Libraries加入json

C++語言

  1. 安裝需要的package # sudo apt-get install libjsoncpp-dev (ubuntu)
  2. 建立一個C++專案將下列程式碼加入
#include <iostream>       // std::cout
#include <string>         // std::string
#include <json/json.h>

int main() {
        std::string raw = "{\"key\":\"value\",\"我\":\"是誰\",\"array\":[\"a\",\"b\",123]}";
        Json::Reader reader;
        Json::Value value;
        std::cout << "Input: " << raw << std::endl;
        if (reader.parse(raw, value)) {
                std::cout << "parsing: " << value ;//<< std::endl;
                std::cout << "get: " << value["我"] ;//<< std::endl;
                std::string data = value["key"].asString();//toStyledString();
                std::cout << "string: [" << data << "]" << std::endl;

                // with -std=c++11
                std::cout << "---" << std::endl;
                for (auto it : value) {
                        std::cout << "elm: " << it ;//<< std::endl;
                        if (it.isArray()) {
                                for (auto it2 : it)
                                        std::cout << "array data: " << it2 ;//<< std::endl;
                        } 
                }         
        } 
        return 0;
}

       3.  點專案再按右鍵->Properties->C/C++ General->Paths and Symols ->Includes加入/usr/include/jsoncpp/json
       4.  接下來選C/C++ Build->Settings->GCC C++ Linker->Libraries加入jsoncpp
       5.  接下來選C/C++ Build->Settings->GCC C++  Compile->include加入/usr/include/jsoncpp/,/opt/local/include/
       6.  接下來選C/C++ Build->Settings->GCC C++  Compile->Dialect->Language standard 選   ISO C++11(-std=c++0x) PS:因為這個測試函數用到C++11的語法。
  

2015年2月12日 星期四

在Ubuntu 14.04使用eclipse創建JNI流程

建環境

1.下載jre與jdk
1.下載eclipse & eclipse CDT
2. 解壓縮eclipse與eclipse CDT並將eclipse CDT中的plugins與features copy到eclipse中

創建JNI流程

產生 JNI *.h檔

1.打開eclipse  建立一個Java project 

public class HelloJNI 
{
   static {
      System.loadLibrary("libHelloJNI"); 
   }
   private native void sayHello();
}
  1. HelloJNI project 按右鍵,選New->Other,再選 C/C++, Convert to a C/C++ Project (Adds C/C++ Nature)->Next.
  2. 當"Convert to a C/C++ Project" 視窗跳出來後.在 "Project type", 中選 "Makefile Project" ,在 "Toolchains", 中選 "Linux GCC",然後點擊 Finish. 
  3. 在project裡增加一個資料夾"jni"在jni中增加一個檔案makefile 內容如下
# Define a variable for classpath
CLASS_PATH = ../bin

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

# $* matches the target filename without the extension
HelloJNI.h : HelloJNI.class
 javah -classpath $(CLASS_PATH) $*

    4.  選makefile 點擊右鍵選 Make Targets->Create...然後跳出一個對話框

     CreateMakeTarget_hello_jni_h.png
   5.  接下來執行makefile->Make Targets->Build 跳出對話框後選擇HelloJNI.h然後按Build將會在jni資料夾中產生HelloJNI.h。

產生Share library  *.so

  1  .在eclipse創建一個c project "HelloJNI",Project type選Shared Library,
        Toolchains選linux GCC 按finish
   2.  將步驟5產生的HelloJNI.h 複製到HelloJNI這個project然後實作HelloJNI裡宣告的函數
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
 
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) 
{
   printf("Hello World!\n");
   return;
}

    3. 然build all一次,會出現一些 error
        1.Fatal error : jni.h : No such file or directory
         解法:選擇Project->Property->C/C++ General ->Paths and Symbols->include
                   Languages->GUN C 再按 Add 將JAVA_HOME裡的include以及include/linux加入                            然後按ok再編譯一次。
        2.Description Resource Path Location Type ./main.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC HelloJNI
          解法:選擇project->Property->C/C++ Build->GCC Compileer->Miscellaneous勾選(-fPic)
        3.*** no rule to make target all'. stop
           解法:
                   1.網路上有人的作法是Project->Property->C/C++ Build->Behavior->Build(incremental build) Text edit中的all清除。
                   2.但我的情況是被其他專案干擾只要將干擾的專案關掉即可。
   
          4.接下來在Release/Debug資料夾將產生libHelloJNI.so檔

將JNI加入JAVA的專案裡

  1. 將HelloJNI.java加到測試專案TestJNI裡 
 TestJNI.java程式碼:

public class TestJNI { public static void main(String[] args) { // TODO Auto-generated method stub new HelloJNI().sayHello(); } }

2. 在專案裡增加一個資料夾jni再將libHelloJNI.so放入jni資料裡
      3. 直接執行會發生錯誤
          Exception in thread "main" java.lang.UnsatisfiedLinkError: no libHelloJNI in java.library.path
原因是找不到libHelloJNI.so檔
解法: 1.設定好 eclipse JAVA Build Path          2.在程式碼中使用System.load(System.getProperty(java.class.path)+"/"+libHelloJNI.so);             來代替System.loadLibrary("libHelloJNI");即可

參考:
http://www.bogotobogo.com/cplusplus/eclipse_CDT_JNI_MinGW_64bit.php


         






Ubuntu的系統下的Eclipse的安裝及不能啟動的解決辦法(轉載)

1.最簡單的安裝方法是在Ubuntu的軟件中心在線安裝,如下圖所示:
Eclipse的安裝後的目錄結構如下:
(1)系統文件在“的\ usr\ lib目錄\月食”下,約120MB,主要目錄及文件如下圖所示:



(2)共享的系統文件在“usr/shar/eclipse”,約24MB,主要目錄及文件如下圖所示:


(3) 啟動的shell腳本在”usr/bin”中,如下圖所示:


2.安裝後,啟動Eclipse提示如下錯誤信息,不能啟動。下面分析原因並給出解決辦法。
按錯誤信息給出的路徑(注:.eclipse是隱藏的目錄),找到1379144725995.log日誌文件,主要內容如下:
java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: 
    no swt-gtk-3740 in java.library.path 
    no swt-gtk in java.library.path 
    Can't load library: /home/zgj/.swt/lib/linux/x86/libswt-gtk-3740.so 
    Can't load library: /home/zgj/.swt/lib/linux/x86/libswt-gtk.so 
          ….............. 
從以上內容可以看出:原因是不能加載/home/zgj/.swt/lib/linux/x86/ 下的一系列文件(8個.so文件),這些.so文件存放在“/usr/lib/ jni/”目錄下,如下圖所示:
可見:只需把這些.so文件複製或鏈接到/home/zgj/.swt/lib/linux/x86/ 目錄下即可。
zgj@reawish:~$  ln -s /usr/lib/jni/libswt-*  ~/.swt/lib/linux/x86/ 
執行命令後, /home/zgj/.swt/lib/linux/x86/ 目錄下就存放了這些.so文件的鏈接,如下圖所示:



總結: 
32bit系統: 
ln -s /usr/lib/jni/libswt-*  ~/.swt/lib/linux/x86/ 
或者
cp /usr/lib/jni/libswt-*  ~/.swt/lib/linux/x86 

64bit系統: 
ln -s /usr/lib/jni/libswt-*  ~/.swt/lib/linux/x86_64/ 
cp /usr/lib/jni/libswt-*   ~/.swt/lib/linux/x86_64 

3.啟動Eclipse,測試一下Java程序運行的運行情況,測試結果正常,如下圖所示:

eclipse 執行 native code 發生 Exception in thread "main" java.lang.UnsatisfiedLinkError: no libXXX in java.library.path 的錯誤訊息

這是JAVA找不到*.so檔
一般是使用System.loadLibrary("libXXX") 來載入lib但是在我的環境會發生" Exception in thread "main" java.lang.UnsatisfiedLinkError: no libXXX in java.library.path" 的錯誤訊息
1.設定Java Build Path->Source->Native library location選so檔放的路徑也無效
2.設定Java Build Path->Libraries->Native library location選so檔放的路徑也是無效
PS:System.loadLibrary("libXXX") 會到 java.library.path 所指明的檔案夾去載入適當的 native library。
再來使用System.load(String)函數來嘗試
1.設定好 eclipse JAVA Build Path
2.在程式碼中使用System.load(System.getProperty(java.class.path)+"/"+libXXX.so);

ps:System.load(String) 則可以從指定 local file system 上的某個檔案來載入。

could not find class file for 'HelloJNI'

source java

package eMMC_Test;

public class HelloJNI {
static {
System.out.println(System.getProperty("java.library.path"));
System.load(System.getProperty("java.library.path")+"/"+"libHelloJNI_c.so");
//System.loadLibrary("libHelloJNI_c");
}
public native void sayHello();

$javah -jni HelloJNI 
出現could not find class file for 'HelloJNI'的錯誤訊息

使用網路上一些解法 Ex .-classpath和com.package.myclass包名都沒用
解法1.創建一個default package不用指定package執行javah -jni HelloJNI 可以過。
解法2.cd到bin那一層執行javah -jni eMMC_Test.HelloJNI 也可以解決。


參考:http://dannyshi.iteye.com/blog/1995070