2011-09-26 21 views
3

我有2個部分的應用程序,德爾福和C,我有2個問題 1.什麼是最快的方式傳遞參數到德爾福?更快的參數傳遞在德爾福/ C

procedure name(Data: string); // Data is Copied to another location before passing so its slow 
procedure name(var Data: string); // Data is Passed by pointer, Faster 
procedure name(const Data: string); // unknown 
  1. i加在C指針想傳遞參數,我有一個字符數組和一個功能,我不想通過整個陣列,切它的一個第一部分,並通過其餘部分

    void testfunction(char **Data) 
    { 
        printf("Data = %d\n", *Data); 
        return; 
    } 
    
    int main() 
    { 
        char Data[] = "TEST FUNCTION"; 
        testfunction(&&Data[4]);  // Error 
        return 0; 
    } 
    

感謝

+1

如果您需要將字符串數據從C dll傳遞給Delphi,請在delphi界面中使用PAnsiChar或PWideChar類型,這與LPCSTR(char *)和LPWSTR(wchar_t *)等效。 –

+1

@Warren'LPCSTR'實際上是'const char *'。通常情況下,你會配對LPSTR和LPWSTR或者LPCSTR和LPCWSTR。 –

+1

這是正確的。我無法再編輯該評論,所以感謝您的注意。 –

回答

6

德爾福字符串駐留在堆上,並總是通過指針傳遞。你的第一個按值傳遞的例子是不正確的。按值傳遞的字符串不會被複制。只有參考被複制。對於字符串來說這是可能的,因爲它們具有魔法寫入時複製行爲。通過值傳遞的動態數組被複制。

傳遞字符串時使用const具有最佳性能,因爲編譯器可以優化引用計數代碼。

你的C代碼有點困惑。你不想要char**,而是想要char*。請記住,C字符串char*只是一個指向空終止的內存塊的指針。由於它已經是一個指針,因此不需要將指針指向C字符串。

而你的意思是%s而不是%d肯定。要傳遞從第5個字符開始的C字符串,請寫入Data+4

void testfunction(char *Data) { 
    printf("Data = %s\n", Data); 
} 

int main() { 
    char Data[] = "TEST FUNCTION"; 
    testfunction(Data+4); 
    return 0; 
} 
+0

是的,我的意思是%s,抱歉,這是否也會抱怨c?我的意思是,傳遞char *並在函數內修改它與delphi相同? – killercode

+1

@killercode C字符串與Delphi字符串完全不同。在C中,你需要自己管理緩衝區。你可以修改C字符串中的字符,但如果你想在C中使用'var s:string',那麼你確實會使用'char **'。但是之後你需要釋放舊字符串並重新分配一個新字符串(如果需要擴展它)。沒有引用計數等等。我用'char *'因爲你沒有修改。這是爲什麼人們使用C++而不是C的原因之一。 –

+0

ok,所以delphi中最快的是const? – killercode

2

的代碼是有點誤導我猜。它是否打算只打印「功能」?如果是這樣的:

void testfunction(const char *Data) 
{ 
    printf("Data = %s\n", Data); 
    return; 
} 

int main() 
{ 
    char Data[] = "TEST FUNCTION"; 
    testfunction(Data+4); 
    return 0; 
} 

這將數組它的其餘部分在通過所述串從索引4(包括)該函數。 通過傳遞char *,您不會複製該函數的本地堆棧中的字符串。只是指向該內存開始的指針。

1

我只能回答德爾福部分(我的C是有點生疏剛纔和C指針/數組引用使我的頭不疼的時候我上午當前和最新的)

字符串是指針並始終通過引用傳遞,所以數據不會在傳遞-EVER時被複制。

然而,在該

procedure test(s:String); 

的情況下指針S被通過,如果修改S中的程序測試中,生成一個唯一的字符串,並分配至S新指針,而不是原來的傳遞變量。您可以通過串litterals和字符串表達式/修改於

procedure test(var s: String); 

地址指針S被通過,

指針S被通過飛(「唧唧歪歪」 S +),如果你在過程測試中修改S,生成一個唯一的字符串(如果需要)以及分配給S的新指針,以及原始傳遞的變量。你永遠無法通過串litterals和字符串表達式/修改上飛(S +「唧唧歪歪」)

procedure test(const s: string); 

指針S被通過,你不能修改程序測試期間在s。 (好吧,你可以耍着和愚弄的編譯器,但它是醜陋,很難做到,通常需要大量的類型轉換)

+0

這有點複雜。即使您不修改string.dify字符串,通過值傳遞的簡單傳遞也會引用計數開銷。使用const避免了這一點。 –

+0

@David Heffernan - >啊是的,我忘了他們增加了記憶值。儘管如此,還是遠遠低於問題思想者正在發生的問題的完整副本。 –

+0

嗯,是比不完整的副本,沒有發生! ;-)如果通過value和const之間的差異顯着,我會感到震驚。 –

3

沒人做強調衆所周知的事實,即自2009年德爾福,string = UnicodeString因此將被導出爲PWideChar/LPCWSTR而不是PChar/LPCSTR。值得注意的是,恕我直言,因爲它可能會令人困惑,如果它不夠清晰,並期望您的代碼與所有版本的德爾福一起工作。

如果你想修改從C庫中的字符串內容,你或許應該使用WideString德爾福類型,而不是一個stringWideString由Windows分配和處理(這是COM/Ole字符串),因此您有相應的C API來處理這些OLESTR指針。而這WideString不會受到德爾福2009年Unicode中斷(它一直是Unicode)。

當然,WideString慢於string(有幾個原因,最主要的是爲WideString慢得多堆分配 - 因爲Vista的越來越好),但它是恕我直言,出口一些文字數據的安全跨語言的方式來自Delphi應用程序和庫(在Windows世界中)。例如,.Net世界將喜歡編組那些OLESTR類型的變量。