2011-11-24 120 views
3

我已經在C#中編寫了一個dll,提供了一個可供使用的類。該DLL由我編寫的C程序調用。 (它是一些程序的插件,我必須用C語言編寫插件的代碼,但我想使用.NET的功能,因此是dll)。如何在C#dll中保留一個對象「持久化」?

在DLL中,我想開一個流和做其他的東西,應該是兩次調用DLL之間持續。以下代碼由私有成員Connector表示。

namespace myCSharpDll 
{ 
    // the c++ program calls this methods 
    public interface IAccess 
    { 
     double Initialize(); 
     double Timestep(double time, double[] values); 
     ... 
    } 

    // E is the beginning of another program my dll should connect to, therefore the names 
    public class EAccess : IAccess 
    { 
     // EConnector is another class I defined in the same dll 
     private EConnector Connector; 

     public double InitializeE() 
     { 
      Connector = new EPConnector(); 
     } 
     public double Timestep(double time, double[] values) 
     { 
      return Connector.Connect(); 
     } 

當我調用InitializeE()和更高版本到Timestep()時,Connector oject指向NULL。

我有什麼做的,當我打電話時步()從我的C代碼,我可以訪問連接的創建之前實例?

我大概是在錯誤的方向搜索。任何提示都表示讚賞。

+2

請向我們展示您的C++代碼。另外,C!= C++。 – SLaks

+0

已解決。謝謝大家。感謝SLaks - 通過我的C/C++代碼向你展示給我看的錯誤。/Stackoverflow不讓我發佈答案,因爲我沒有收集到足夠的聲望點。但它會讓我在8小時內。然後我發佈答案。 – Teetrinker

回答

0

感謝SLaks詢問我的C/C++代碼。這就是問題所在。這比我想象的更簡單。我把代碼放在一起給你看。


我知道C和C++是不一樣的,插件結構只是有點奇怪。大部分代碼都是由嚮導生成的。我只需填寫我的代碼。這是一個cpp文件,但代碼似乎是C.嗯,我認爲這是脫離主題。

在這裏,我提出了最重要的線。

// the dll is connected via COM, using the type library file that regasm generated 
#import "[path]\myCSharpDll.tlb" raw_interfaces_only 
using namespace myCSharpDll; 

static void OnActivate (IfmDocument, Widget); 

//off topic: this are the weird lines the wizard put in my way 
#ifdef __cplusplus 
extern "C" 
#endif /* __cplusplus */ 

// when the plugin is called by the host program, this function is called 
static void OnActivate (IfmDocument pDoc, Widget button) 
{ 
    InitializeIntermediate(pDoc); 
    Timestep1(...); 
} 

static void InitializeIntermediate(IfmDocument pDoc) 
{ 
    // Initialize COM. 
    HRESULT hr = CoInitialize(NULL); 
    IEPAccessPtr pIEPAccess(__uuidof(EPAccess)); 

    double result = -1; 
    pIEPAccess->InitializeEP (&result); 

    ... 
} 

static void Timestep1(...) 
{ 
    IEPAccessPtr pIEPAccess(__uuidof(EPAccess)); 

    double result = -1.1; 
    pIEPAccess->Timestep (...); 
    ... 

    // now I get a wrong result back here, because this call leads to nowhere as 
    // the connector object in the dll is void 
} 

我意識到,我請求二審與線

IEPAccessPtr pIEPAccess(__uuidof(EPAccess)); 

所以我改變了這一切指向一個單一實例,一切都很好。感謝您的意見!

0

如果我沒看錯你要保持整個c中的使用DLL的一個對象。如果是這種情況,請嘗試類似於單例模式。

http://en.wikipedia.org/wiki/Singleton_pattern

什麼單emphazises是你的一類只創建一個對象,並用它來執行所有你需要的工作。基本上,你可能需要一個功能,做這樣的事情,

public class EAccess : IAccess 
    { 
     private static EConnector Connector 
     public EConnector getConnector(){ 
      if(Connector == null){ 
       Connector = new EConnector(); 
      } 
      return Connector; 
     } 
     public double Timestep(double time, double[] values) 
     { 
      return getConnector().Connect(); 
     } 

    }; 

雖然這是不使用單做事的傳統方式,但我認爲它仍然沒有工作。我可能是錯的。如果我誤解了某些內容,請糾正我。

+0

請注意,這不會考慮多個線程。 –