2009-08-21 53 views
4

我將C庫的頭文件轉換爲D模塊,並想知道如何處理C字符串。我應該如何處理D中的C字符串?

使用DMD 1,這個工程:

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

但使用DMD 2(我個人使用的,但我想這些模塊兩個工作)字符串常量,所以要使用獲得相同的代碼需要工作的模塊

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有效的代碼,並在版本阻止所有的代碼必須是編譯器在編譯的代碼有效代碼,即使代碼止跌」不包含在生成的可執行文件中。所以目前代碼都是在兩者中編譯的,但你必須首先修改別名,正如你可以想象的那樣,這並不理想。

回答

5

您可以使用mixin構造函數來使用在所有版本中都無效的語言版本特定的代碼。例如:

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

關於你的實際問題,我建議做同樣的用C++接口的C庫時,作爲 - 定義一個類型,這對D1 const(char)*爲D2和char*,但在適當的時候只用它(例如,如果函數需要char*來寫入緩衝區,則可能不適合將const(char)*命名爲「charptr」的通用名稱)。 LPCSTR可以工作;)

我不明白「什麼是最好的方式,使他們可變」的問題。

+0

再次您好。我應該付錢給你:]。 mixin技巧不起作用; '錯誤:標識符'charptr'未定義。這就說得通了;我不認爲實際上有任何使用緩衝區的功能,但我會牢記它。 re' LPCSTR':我想,我的unix敏感性會因此而過於冒犯。 'cstring'? – Bernard 2009-08-21 20:55:43

+0

該代碼片段適合我。您是否導入了std.compiler(聲明'version_major'的模塊)? – 2009-08-21 20:59:50

+0

我現在做了;相同的結果。 v2.0.31 – Bernard 2009-08-21 21:02:15

-1

不要爲此使用mixins,這是工作的錯誤工具。你真正需要的是'版本'聲明,你可以在條件編譯頁面閱讀:http://www.digitalmars.com/d/2.0/version.html

它不會編譯/查看針對不同版本的代碼。這允許爲不同的D版本或不同的操作系統的不同的代碼構建不同的代碼。

Mixins可能工作,但它是一個沉重的工具,沒有突出顯示的代碼(在引號內),只是過分複雜的事情。版本聲明非常適合這個問題。

+1

「它不會編譯/查看用於不同版本的代碼。」絕對不正確。'version'語句是一個AST節點,因此在對其進行任何考慮之前進行解析。語言的變化使得有效的代碼不會被解析爲D1,並且您不能將不會解析到'version'語句內的代碼。你認爲'version'語句就像C預處理器(無效的定義塊甚至不是_lexed_),而'version'語句並不是這種情況。 – Bernard 2010-08-29 10:46:41

+0

你好像是對的。我使用以下代碼對其進行了測試,該代碼在刪除註釋時不會顯示錯誤: //版本(ABCDE) // { int a = [5,4]; //} 它看起來應該稍微正確。 這很奇怪,因爲總是可能只有某些版本可編譯的代碼。但仍然使用mixins是錯誤的工具,因爲我們沒有更好的工具:O,我認爲D是完美的...:P – 2010-08-29 21:15:31

+0

您的代碼在那裏_parses_就好了:它是一個類型,一個標識符,和一個數組文字初始化程序。這被解析成一個AST節點就好了。直到編譯器運行一個語義通行證,並且發現類型不匹配以致它出錯。 |我覺得應該在編譯過程的早些時候考慮'version'語句的實際效用。 – Bernard 2010-08-29 23:45:32