2013-08-06 65 views

回答

4
[DllImport("YourDll.dll", CharSet = CharSet.Ansi)] 
//[return: MarshalAs(UnmanagedType.Bool)] // This line is optional, and it's implicit 
static extern bool GetServerName(int index, StringBuilder buffer, int bufSize); 

要使用它:

int bufSize = 100; 
StringBuilder buffer = new StringBuilder(bufSize); 
bool result = GerServerName(0, buffer, bufSize); 

if (result) 
{ 
    string buffer2 = buffer.ToString(); 
} 

技術上的問題是「什麼是相當於LPSTR」 ...的反應是:stringStringBuilder如果傳遞的字符串的方法,StringBuilder如果該方法將字符串傳遞給您。另一種方法是使用byte[],做Encoding/Decoding自己,如:。

[DllImport("YourDll.dll", CharSet = CharSet.Ansi)] 
//[return: MarshalAs(UnmanagedType.Bool)] // This line is optional, and it's implicit 
static extern bool GetServerName(int index, byte[] buffer, int bufSize); 

int bufSize = 100; 
byte[] buffer = new byte[bufSize]; 
bool result = GerServerName(0, buffer, bufSize); 

if (result) 
{ 
    string buffer2 = Encoding.Default.GetString(buffer, 0, Array.IndexOf(buffer, (byte)0)); 
} 

(C字符串是空終止我們找到的第一個\0Array.IndexOf(buffer, (byte)0),我們將字符轉換高達空字符串與Encoding.Default.GetString())。

一些評論...

  1. 我希望你有緩衝的最大長度(如常數),因爲通常這些方法都寫爲以某種方式返回字符串的長度。
  2. 如果你有一個Unicode版本的方法(可能是GetServerNameW),你應該使用它。如果存在,最好使用Unicode方法,所以非Ansi字符不會丟失。

作爲旁註,當您使用DllImport時,應檢查您是否使用了正確的調用約定。對於Windows API,您不需要執行任何操作,但根據頭文件中如何定義方法,您可能需要添加CallingConvention = CallingConvention.something)。通常(但現在總是).NET運行時會在錯誤的調用約定上拋出異常,或者該方法不起作用,並且會返回奇怪的東西或者會崩潰。這是因爲調用約定告訴.NET如何將參數傳遞給方法(技術上在何處,如何以及誰必須釋放堆棧)。頭文件中調用約定的一些示例是cdecl,stdcall,fastcall,thiscall,pascal(相當於stdcall),WINAPI,APIENTRY(相當於WINAPI),CALLBACK(相當於WINAPI)以及所有帶_或__的單詞或全部大寫。 Microsoft VC++通常使用cdecl調用約定爲C方法,而thiscall爲C++方法。你可以通過一些arguments來控制它。

+1

嚴格地說,'CharSet.Ansi'也是隱含的。但這不是我所期望的,所以我從不建議省略它。清晰明確無誤! –

+0

@CodyGray我認爲這是'CharSet.Auto' :-)剛剛檢查,你是對的。但我也總是明確地設置'CharSet'。我不相信'CharSet.Auto' :-) – xanatos

+0

謝謝你,先生......它的工作很好..... – mahua22