2010-08-09 37 views
1

我有一個C++ DLL,我有源代碼。它目前正在登錄到stdout。什麼是通過interop/pinvoke提供從C++ dll到c#應用程序的日誌記錄的方法

我打電話給這個DLL的方法通過從C#pinvoke。

我希望c#代碼能夠獲取日誌消息,然後將它們轉發給c#應用程序自己的日誌記錄機制。

我看到了一些關於捕獲stdout的問題/答案,但我無法讓他們工作。如果有人能爲此提供一個完整的hello world示例,那就太棒了。

否則,我正在考慮改變C++函數來接受某種類型的字符串或流參數,並在函數的返回處填充要讀取的消息。

但是,我該如何使用字符串,因爲C++ dll需要分配內存,什麼可以釋放它?

有沒有辦法讓我傳入流並使用普通的C#流機制從流中讀取,但是在dll裏面讓它像stdout一樣使用通常會是這樣嗎?

幫助!

這個問題很接近,但我不想寫出來的文件,如果類似的東西會捕獲到一個很好的內存流中,但我沒有看到內存流equivilent SafeHandle等。 Redirect stdout+stderr on a C# Windows service

+0

你有沒有考慮遷移到C++/CLI? – 2010-08-09 18:46:00

+0

C++/CLI不會在這個實例中工作。我們最終會調用C++ com庫 – 2010-08-09 18:50:01

+0

從最近的痛苦經歷來看,我不會建議任何人使用C++/CLI,除非他們幾乎沒有別的選擇。 – dlchambers 2012-12-15 16:59:15

回答

1

你可以宣佈你的日誌功能,在你的C++ DLL作爲函數指針,默認爲打印功能到stdout其中,並提供P/Invoke'able功能,將其設置爲不同的回調。
您可以使用Marshal.GetFunctionPointerForDelegate將C#方法傳遞給此函數。

(未經測試!)

C++ DLL (僞代碼)

delegate void logger(char* msg); 

logger log = printf; 

void set_logger(logger l) { 
    log = l; 
} 

void test() { 
    log("Hello World!"); 
} 

C#程序:

static extern void set_logger(IntPtr l); 

static extern void test(); 

static Action<IntPtr> log; 

static void LogToConsole(IntPtr msg) 
{ 
    Console.WriteLine(Marshal.PtrToStringAnsi(msg)); 
} 

static void Main() 
{ 
    log = new Action<IntPtr>(LogToConsole); 
    set_logger(Marshal.GetFunctionPointerForDelegate(log)); 

    test(); 
} 
+0

當垃圾收集器收集Action <>委託實例時,這會非常快速地進行。 – 2010-08-09 19:00:30

+0

記住Action <> delegate實例的某處:-) ...這個例子遠非完美,它只是顯示了它是如何完成的。 – dtb 2010-08-09 19:02:07

相關問題