親牛の開発日記

ぼけ防止するため、開発メモを残そう

Javaアプリのリソースファイル(データ)を取得する際にリソースパスについ

・リソースの取得

すべてのJavaアプリに対し、下記3つのリソースがあれば

src

  main

     java

       com

          pkg

             Main.java

             main.properties

     resources

        template

            1.html

        my.properties

 

それぞれの取得に以下のパスで行う。

・main.properties

ClassLoader.getSystemResource("com/pkg/main.properties")

・1.html

ClassLoader.getSystemResource("template/1.html")

・my.properties

ClassLoader.getSystemResource("my.properties")

ではなぜなのか?実際にコンパイルしたフォルダの構成にかかってる

上記のソースフォルダツリーであれば、コンパイル後に以下のアウトプットをできる

classes

    com

      pkg

         Main.class

         main.properties

    template

        1.html

    my.properties

つまり、リソースのパスはコンパイル後の場所と関係していることが分かりました。

 

 2018/06/11 IntelliJの中に、リソースフォルダの追加方法

stackoverflow.com

Visual Studio CodeでNODE-REDのデバッグ方法

NODE-REDのインストールは、

github.com

で書いてある「Developer」方法でスラスラやればいい。

 

もちろん誰よりも先にNodeJSのインストールを済ませる。

 

NODE-REDを起動する際に以下のコマンドラインで行ってください。

<node-red実施にインストールされたフォルダ>$ node --inspect-brk red.js

※ポイントは「--inspect-brk」オプションを付けること。当方のNodeJSのバージョンはv8.11.1、古い「--debug-brk」で付けると無視される。

 

上記の設定で問題なく起動すると、以下のメッセージを表示される。

Debugger listening on ws://127.0.0.1:9229/ee6542cb-bd43-46e5-b7ce-c681999f11db
For help see https://nodejs.org/en/docs/inspector

 それから、Visual Studio Codeの登場

1.まず、node-redのインストール先フォルダを開く

2.デバッグ設定

f:id:itroad:20180422175855p:plain

3.上記設定を終わったら、アタッチしてデバッグを行いましょう。

 

==以上==

 

C#から文字列の配列をC/C++ DLLへの渡し方

■ネイティブ関数の引数が「char**」の場合

C関数

void init(int argc, char** argv);

C#

[DllImport("XXXXX.dll")]
public static extern int init(int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex =1)]string argv);

これは無難だろう

 

■ネイティブ関数の引数が構造体であって、その中に「char**」があった場合

C構造体

struct ARGS

{

 int argc;

 char** argv;

};

void init(struct ARGS * pArgs);

 

C#

public struct ARGS
{

int Argc;
IntPtr Argv;

public ARGS(string argv)
{
  Argc = argv.Length;
  Encoding encoding = Encoding.GetEncoding(932);
  List<string> list = new List<string>(argv);
  Argv = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)) * list.Count);

  for (int index = 0; index < list.Count; index++)
   {
      int len = encoding.GetByteCount(list[index]) + 1;
      IntPtr point = Marshal.AllocCoTaskMem(len);
      Marshal.Copy(encoding.GetBytes(list[index]), 0, point, len - 1);

      Marshal.WriteByte(point, len - 1, 0);

      Marshal.WriteIntPtr(Argv, index * Marshal.SizeOf(typeof(IntPtr)), point);
   }
}

}

[DllImport("XXXXXX.dll")]
public static extern int Init(ref ARGS args);

JAVAのNative開発(JNI)もろもろ注意

■2番目の引数って何?

Javaから呼び出されるjni関数は、だいたい以下の形式になっている

jxxxxx Java_package_name_クラス名_メソッド名(JEnv*, j???, メソッド引数)

中には2番目の引数(j???)は、Java側のメソッドの宣言によって型が変わってくる

 

private native String A();

jobject Java_package_name_クラス名_A(JEnv*, jobject..)になる

しかし、Aメソッドが「static」で宣言された場合

private static native String A();

jobject Java_package_name_クラス名_A(JEnv*, jclass..)になる

つまり、Java側のメソッドがstatic/非staticによって、2番目の引数は

jobject/jclassに変わってくる。これを注意したい。

 

Android Studio 開発メモ Javahとの連携

  ご存じ通り、Android開発中にJavaクラスからNativeコードを呼び出したり、逆にしたりする際に、JNI規格に従いC Headerファイルの作成やJava側のラッパクラスの用意が欠かせない作業でありますが、とても面倒だと思います。幸いJDK側が「Javah」という便利なツールを提供してくれてコマンドラインで地道に叩けば何とかなりますが、それでも不便と思う方が多いと思います。この作業をAndroid Studioに取り込み開発の効率の向上に繋がればと思います。

 

取り込み手順

1.プロジェクトを開いた状態で、「File」⇒「Settings」メニューをクリックし、「Settings」画面を表示させる。

2.「Settings」画面にて下図のように、「Tools」⇒「External Tools」パネルを特定し、「」アイコンをクリックし、「Create Tool」画面を表示させる。

f:id:itroad:20170218202739p:plain

3.「Create Tool」画面にて、下記情報を入力する。

 ①Name

  ⇒JavaClass To C Header

 ②Description

  ⇒Generate JNI Special C Header File From JavaClass

 ③Program

  ⇒$JDKPath$/bin/javah

 ④Parameters

  ⇒-classpath $Classpath$ -v -jni $FileClass$

 ⑤Working directory

  ⇒$SourcepathEntry$\..\cpp

 

$...$で囲んているのは、マクロ変数である。③~⑤項目の右側にある「Insert macro…」ボタンをクリックすることで、「Macros」画面を呼び出し、そこから自分に必要なマクロ変数を選んで、追加できる。(画面操作についてここで割愛)

※「Options」および「Show in」項目は一応全部入れて、より詳しい情報を得るには無難でしょう。

f:id:itroad:20170218202839p:plain

f:id:itroad:20170218202910p:plain

使用上に注意事項

  基本的に、プロジェクト上にあるJavaクラスファイルを選んで、右クリックして、コンテキストメニューからの「External Tools」⇒「JavaClass To C Header」を呼び出すだけで済みます。

  ただ、Android Studioは、プロジェクトをビルドしないとJavaクラスをコンパイルしてくれないクセがあるので、使用前に自ら「Build」⇒「Make Project」を行うほうが無難でしょう。特にJavah」が下記エラーが発生する場合、必ず自前でビルドしてください。

エラー:’クラスのフルネーム’ のクラス・ファイルが見つかりませんでした。