2009-08-21 12 views
4

私はCライブラリのヘッダーファイルをDモジュールに変換していますが、どのようにC文字列を処理すべきか不思議でした。文字列がその使用して同じコードを取得するには、constのあるDでC文字列をどのように扱うべきですか?

void f(char* s); // Definition for C library's function. 

しかし、DMD 2使用して(私は個人的に使用しますが、私はモジュールは、両方のために働きたい):DMD 1、この作品を使用して

必要なモジュール

void f(const(char)* s); // Definition for C library's function. 

どうすればよいですか? char*を使用して、 'クライアント'コードで文字列を何とか変更できるようにしますか?または、コードをコンパイルするコンパイラのバージョンに応じて型を変更しますか?前者の場合、それらを変更可能にする最良の方法は何ですか?私は.dupがそれをするだろうと思ったが、コンパイラはそれのバーを持っていなかった。後者の場合、私はそれをどうやってやりますか?

version (D_Version2) { 
    alias const(char)* charptr; 
} else { 
    alias char* charptr; 
} 

void f(charptr s); 

しかし、悲しいかな、DMD 2バージョンがDMD 1のための有効なコードではなく、バージョンブロック内のすべてのコードは、コードをコンパイルするコンパイラのための有効なコードでなければならない、でもコードwouldn」の場合:私はこれを試してみました結果の実行可能ファイルに含める必要があります。したがって、現在のところ、コードは両方でコンパイルされますが、あなたが想像するようにエイリアスを最初に修正する必要があります。これは理想的ではありません。

答えて

5

構文mixinを使用すると、すべてのバージョンで有効でない言語バージョン固有のコードを使用できます。例:あなたの実際の質問について

static if(version_major<2) 
{ 
    alias char* charptr; 
} 
else 
{ 
    mixin("alias const(char)* charptr;"); 
} 

、私はC++とCライブラリをインタフェースする場合と同じようにやってお勧めします - 、D2のためのconst(char)*とD1のためchar*の型を定義しますが、適切な場合にのみ、例えば(それを使用しますバッファが書き込みを行うために関数がchar*を受け取った場合、const(char)*という名前を "charptr"という一般的な名前にするのは適切ではないでしょう)。 LPCSTRが動作する可能性があります;)

「私はそれらを変更可能にする最良の方法は何ですか?」という質問は理解できませんでした。

+0

もう一度。私はあなたに支払うべきです:]。ミックスイントリックは機能しません。 'エラー:識別子 'charptr'が定義されていません。それは理にかなっている;実際にはバッファを使用する関数はないと思いますが、私はそれを念頭に置いています。 re 'LPCSTR':私のUNIXの感性はこれであまりにも怒られるでしょう、と私は思います。 'cstring'? – Bernard

+0

コードスニペットは私にとっては役に立ちます。 'import std.compiler'(' version_major'が宣言されているモジュール)でしたか? –

+0

私は今でした。同じ結果。 v2.0.31 – Bernard

-1

ミックスインを使用しないでください。これは間違ったツールです。あなたが本当に必要とするのは 'version'ステートメントです。ここで条件コンパイルのページで読むことができます:http://www.digitalmars.com/d/2.0/version.html

異なるバージョンのコードはコンパイルしません。これにより、異なるバージョンのDまたは異なるOSの異なるコードを作成することができます。

ミックスはおそらく動作しますが、重いツールであり、強調表示されたコード(引用符の中に)がなく、複雑すぎるものです。バージョンステートメントはこの問題に完全に適しています。

+1

"異なるバージョンのコードをコンパイル/ルックアップしません。"絶対に間違っている。'version'ステートメントはASTノードであるため、それを削除することを検討する前に解析されます。言語の変更により、有効なD2がD1として解析されないコードが作成され、 'version'ステートメントの内部で解析されないコードを置くことはできません。あなたは、 'version'ステートメントがCプリプロセッサのように動作すると考えています(無効なdefineブロックも_lexed_ではありません)。これは' version'ステートメントでは当てはまりません。 – Bernard

+0

あなたは正しいと思われます。コメントを削除したときにエラーが発生しない次のコードでテストしました。 // version(ABCDE) // { int a = [5、4]; //} それはちょっと正しいはずです。 これは変わっています。特定のバージョンでのみコンパイル可能なコードが常に存在する可能性があるからです。しかし、mixinsを使うのは間違ったツールです。私たちはより良いツールを持っていませんか?O:私はDが完璧だと思っていました...:P –

+0

あなたのコードはそこにあります_parses_:配列リテラル初期化子。それはちょうどうまくASTノードに解析されます。コンパイラがセマンティック・パスを実行して、タイプがエラーと一致しないことがわかるまではありません。 |私は、 'version'ステートメントはコンパイルプロセスの早い段階で実際のユーティリティであると考えられるべきだと感じています。 – Bernard

関連する問題