2013-04-25 38 views
3

我正在使用RGiesecke DLLExport庫來生成可以從構建於VC6上的舊應用程序中動態加載的C#DLL。它導出方法,並從VC6代碼中調用它們。沒問題。但是,只要我試圖聲明一個變量作爲我的.NET類中的任何一個,它就會崩潰。非託管導出(DLLExport)崩潰

//I tried CallingConvention = CallingConvention.StdCall too 
    [DllExport(CallingConvention = CallingConvention.Winapi)] 
    static void GetDwgReferences(string fileName) 
    { 
     //OK: inialize System classes of .net 
     DateTime dateTime = DateTime.Now; 

     //crashing here: declare a variable of my static class (.net assemebly) 
     //SafeString safeString; 

     //crashing here: declare a variable of my class (.net assemebly) 
     //Email email; 

     //crashing here: initialize an object of my class (.net assemebly) 
     //DwgXrefs dwgXrefs = new DwgXrefs(); 

     //crashing here by declcare a variable of third-party library (.net assemebly) 
     //ExSystemServices _serv; 
    } 

怎麼了?請幫忙。

回答

2

我有一個類似的問題,試圖在Metatrader中使用非託管導出來加載相關的託管dll。

經過一番挖掘,我想我已經找到了問題。應用程序領域可能不是你期望的那樣,CLR正試圖解決你的程序集,但是因爲一個不起眼的錯誤而失敗。在我的情況下,應用程序域實際上是在主機應用程序的目錄中執行的,所以我認爲情況總是如此。

我會建議你做的是建立在一些不依賴裸DLL和地點如下所示:

static void Initialize() 
{ 
     SimpleLog.WriteLog("App -" + AppDomain.CurrentDomain.BaseDirectory); 
} 

[DllExport("Test", CallingConvention = CallingConvention.StdCall)] 
public static void Test() 
{ 
    Initialize(); 
} 

我不知道,但我想你可能不能在這裏使用一個靜態構造函數?

在日誌中,您應該看到該域的執行目錄。如果你把你的裝配在這裏(希望)應該可以工作。它已經爲我解決了這個問題。我想下一個問題是我們可以在運行時更改域,因爲我可能不想在這裏放置這些程序集。

有一個谷歌,如果你需要一個簡單的記錄器的源代碼 - 顯然不要使用與DLL依賴關係的第三方日誌記錄框架!

我認爲我是這樣的一個改編: http://www.codeproject.com/Articles/80175/Really-Simple-Log-Writer

0

由於對方回答說,這是很難知道C#是沒有每個方法中明確地捕捉錯誤在try/catch塊拋出了什麼錯誤的C#DLL。

您可能需要導出爲CallingConvention.StdCall和另外元帥傳入字符串作爲一個非託管LPWSTR類型:

[DllExport(CallingConvention = CallingConvention.StdCall)] 
static void GetDwgReferences([MarshalAs(UnmanagedType.LPWStr)] string fileName) 
{ 
} 

請參閱Code to Export C# DLL to Metatrader Build 600+使用羅伯特捷的C#項目模板的託管輸出導出工作示例傳統應用程序(MT4)的C#dll。

此外,您可能會發現Native and .NET Interopability有趣,雖然它主要是爲了從.NET中訪問本機代碼。