2011-03-08 13 views
7

假設我有x.dll在C++中,看起來像這樣如何指定是否取得編組字符串的所有權?

MYDLLEXPORT 
const char* f1() 
{ 
    return "Hello"; 
} 

MYDLLEXPORT 
const char* f2() 
{ 
    char* p = new char[20]; 
    strcpy(p, "Hello"); 
    return p; 
} 

現在,假如我想用這個在C#

[DllImport("x.dll")] 
public static extern string f1(); 

[DllImport("x.dll")] 
public static extern string f2(); 

有沒有辦法告訴CLR採取強烈的主人翁從f2返回的字符串,但不是f1?問題在於,從f1返回的字符串最終會被GC釋放,刪除或其他任何事實,這同樣不利於從f2返回的字符串。希望問題清楚。在此先感謝

回答

4

如果您對dll實現有任何影響,那麼我強烈建議您不要像您在示例中顯示的那樣執行此操作。否則,請細化這個問題來提一下這個約束。

如果你必須從dll返回一個堆分配的字符串,那麼你還應該提供一個清理函數(當從dll導出動態分配的內存時總是很好的做法)。您P /調用分配函數並返回IntPtr,然後用Marshal.PtrToString...之一的http://msdn.microsoft.com/en-us/library/atxe881w.aspx進行編組,然後通過調用事件本機方的清理函數結束。

另一種方法是使用BSTR(從Marshaling BSTRs in COM/Interop or P/Invoke爲例):

母語:

__declspec(dllexport) 
void bstrtest(BSTR *x) 
{ 
    *x = SysAllocString(L"Something"); 
} 

管理:

[DllImport("mydll.dll")] 
extern static void bstrtest(ref IntPtr dummy); 

static void Main(string[] args) 
{ 
    var bstr = IntPtr.Zero; 
    bstrtest(ref bstr); 

    var text = Marshal.PtrToStringBSTR(bstr); 
    Console.WriteLine(text); 

    Marshal.FreeBSTR(bstr); 
} 

我剛剛發現SO一個類似的問題:PInvoke for C function that returns char *

+0

謝謝。抱歉,我無法對您提供任何幫助(達到每日限額),您提供的鏈接就是我需要的! – 2011-03-08 21:41:27

+0

@阿門:你明天總是可以回來......;) – 2011-03-08 23:05:51

相關問題