

今，C++で書かれたソースをJavaに変換しようとしているのですが，  
マクロを展開し，書き換えるのに困っています．  
特に，#define , #ifdef/#ifndef の展開に困っています  
どなたかこの変換のやりかたを教えていただけないでしょうか…


CC BY-SA 3.0
2015-02-11T14:50:47.817
6329
2015-04-03T03:47:17.470
2015-04-03T03:47:17.470
49
8224
question
java preprocessor
Javaで，C言語でのマクロを使用するために


Java 言語には C 言語のマクロと同等のものはありません。

ただ、昔からこういう変換は、`public static final ...` で定義されるような変数で行うことが多いです。

## ■ マクロを使った定数

[code]

    // C
    #define MENU_WIDTH 100
    #define PAGE_WIDTH ( MENU_WIDTH + 500 )
    
[/code]

[code]

    // Java
    private static final int MENU_WIDTH = 100;
    private static final int PAGE_WIDTH = MENU_WIDTH + 50;
    
[/code]

## ■ マクロを使った関数

[code]

    // C
    #define multiply( d1, d2 ) ( d1 * d2 )
    
[/code]

[code]

    // Java
    private static double multiply(double d1, double d2) { return d1 * d2; }
    
[/code]

## ■ マクロ定義で分岐: `#define` ~ `#ifdef`/`#ifndef` ~ `#endif`

[code]

    // C
    #define IS_AMIGA500
    ...
    #ifdef IS_AMIGA500
    ...
    #endif
    
[/code]

### - コンパイル時に決める

`private static final boolean` 定数に対する `if (...) {...}`
分岐は、コンパイラにより(また実行環境により)最適化されますので、以下の方法がよいでしょう。

[code]

    // Java
    private static final boolean IS_AMIGA500 = true;
    
    ...
        if ( IS_AMIGA500) {
            ...
        }
    
[/code]

### - 実行時に決める

また、実行時に定数値を Java VM に渡す方法もあります。

[code]

    // Java
    private static final boolean IS_AMIGA500 = "true".equals(System.getProperty("IS_AMIGA500"));
    
    ...
        if ( IS_AMIGA500) {
            ...
        }
    
[/code]

[code]

    $ # Console
    $ java -DIS_AMIGA500=true MainClass
    
[/code]


CC BY-SA 3.0
2015-02-11T15:34:17.437
6337
2015-02-11T15:53:52.490
2015-02-11T15:53:52.490
4978
4978
6329
answer


Ｃでのマクロをjavaのコードで１００％置き換えるのは、おそらくムリです。

それで、  
１．マクロ展開済みのソースをjavaに変換する。  
というのが第一案。  
ＧＣＣ の場合 `-E -P` のようなオプション。  
Ｖｉｓｕａｌ Ｃ＋＋の場合、 `/EP` のようなオプション  
を使用することで展開済みのソースが得られます。  
例：  
`g++ test.cpp -E -P -o test.cp`

２．Ｃのプリプロセッサをマクロを含んだjavaソースに適用する。  
というのが第２案。  
プリプロセッサの部分が独立したプログラムになっている場合、  
（ＧＣＣの場合は`cpp` がプリプロセッサプログラムです）  
ソースコードをプリプロセッサプログラムにかましてやります。  
例：  
`cpp test.java -o C2Java.java`

拡張子を仮に変更してやれば  
`g++ test.java.c -E -P -o Test.java`  
のようなことでも可能だと思います。

この場合にはやはりjavaコードへの１００％の適用はできないかもしれないです。


CC BY-SA 3.0
2015-02-11T16:07:23.223
6339
2015-02-11T16:07:23.223
5044
6329
answer


C++のアプリケーションはDLL化してしまって、JavaからはJNIで呼ぶってのはいかがでしょう？


CC BY-SA 3.0
2015-04-03T00:18:10.997
8705
2015-04-03T00:18:10.997
2383
6329
answer