2013-12-14 48 views
1

我在D中創建一個窗口,CreateWindowA函數需要基本上指向字符,C字符數組的指針。D風格陣列到C風格陣列

如何將D風格的數組(char[])轉換爲C風格的數組(char*)?

+1

」喜歡冒着緩衝區溢出的代碼可以將指針從數組中嚇跑(通過使用'arr.ptr')「 - 來自官方教程,2分鐘後發現搜索結果。 – 2013-12-14 22:45:22

+1

@ H2CO3通常這是一個壞主意,因爲D字符串不是空終止的,C字符串通常是。將'ptr'傳遞給一個C函數只有在它接受了這個長度並且不會在它傳遞的數組中尋找一個空終止符時才起作用。 –

+0

@JonathanMDavis確切地說(但是傳遞一個明確的長度通常是一個更好的主意......) – 2013-12-14 23:31:01

回答

5

兩個函數在看通常std.string.toStringzstd.utf.toUTFz

toStringz會將string轉換爲immutable(char)*,您可以將它傳遞給C函數,該函數需要const char*。如果它可以確定string是空終止的(通常只是字符串文字的情況,其中有一個空終止符通過它們的結尾),那麼它將不分配並且將僅使用stringptr屬性,但在大多數情況下,它會分配。

toUTFz將從任何字符串類型轉換爲任何字符指針類型。由於所有用於Windows的W功能都採用UTF-16,但它也可用於轉換爲char* - 例如,它可能最常用於轉換爲Windows的const(wchar)*str.toUTFz!(char*)()。像toStringz,它會盡量不分配,如果它可以確定它是不必要的,但它幾乎總是有必要的。

現在,對於您的特殊情況,您正嘗試使用Windows中的A函數之一。這幾乎總是一個壞主意,我強烈建議不要這樣做。使用toUTFz將您的string轉換爲const(wchar)*並將其傳遞給CreateWindowW。 AFAIK,A功能的唯一優勢是它們可以在Win2K之前使用。關於他們的一切都更糟。但是,如果由於某種原因,您堅持使用A函數,那麼您將不得不使用std.windows.charset.toMBSz,因爲A函數不採用UTF-8而是採用「Windows 8位字符集」,並且toMBSz會將字符串轉換爲該格式。 「

+0

我使用Windows-ASCII函數的原因是因爲我無法在'core.sys.windows.windows'模塊中找到廣泛的函數,因此我總結出D沒有實現這些函數。 –

+0

@JeroenBollen所需要的只是函數原型,所以如果druntime由於某種原因沒有它,你可以自己聲明它。但是,大多數使用Windows API的D程序員使用的是http://www.dsource.org/projects/bindings/wiki/WindowsApi,它比druntime更完整。 –

+0

所以我可以做一些像'extern(Windows)void * CreateWindowW(...);',它會工作嗎?沒有需要鏈接的外部庫或要包含的模塊? –

3

你抓住D數組的ptr字段。和length字段搶長度

然而,如果你需要一個C風格的字符串,那麼你需要toStringz方法,將添加空終止符並返回指向第一個字符的指針。 k EEP對它的引用,如果API不創建它自己的拷貝工作由GC避免懸擺指針

+1

一般而言,這是正確的。但是,對於Windows'A'函數,它不是,因爲它們採用'char',但它們不使用UTF-8。你需要'std.windows.charset.toMBSz'。 –