2011-11-24 4 views
3

나는 C#에서 dll을 작성하여 사용할 클래스를 제공했다. dll은 제가 작성한 C 프로그램에 의해 호출됩니다. (그것은 일부 프로그램의 플러그인입니다. 플러그인 코드를 C로 작성해야하지만, .NET의 기능을 사용하려면 dll을 사용하고 싶습니다.)C# dll에서 개체를 "영구적으로"유지하는 방법은 무엇입니까?

dll에서 스트림을 열고 dll을 두 번 호출하는 사이에 지속되어야하는 다른 작업을 수행하려고합니다. 이는 개인 회원 커넥터가 다음 코드에서 나타내는 것입니다.

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에 전화()와 타임 스텝에 나중에 한() oject 점 NULL로 커넥터를 만들 때.

C 코드에서 Timestep()을 호출 할 때 작성한 인스턴스의 Connector에 액세스 할 수 있습니까?

아마도 잘못된 방향으로 검색했을 것입니다. 모든 팁을 부탁드립니다.

+2

C++ 코드를 알려주십시오. 또한, C! = C++. – SLaks

+0

해결되었습니다. 감사합니다 여러분. 감사합니다 SLaks - 내 C/C++ 코드를 통해 당신에게 보여주기 위해 버그를 보여 줬어./나는 충분한 평판 포인트를 수집하지 않았기 때문에 Stackoverflow 내가 대답을 게시하게하지 않습니다. 그러나 그것은 8 시간 만에 나를 가능하게 할 것입니다. 나는 대답을 게시한다. – Teetrinker

답변

0

내 C/C++ 코드를 묻는 질문에 대한 SLAKs. 그것이 문제의 위치입니다. 내가 생각했던 것보다 더 간단했다. 나는 당신에게 보여주기 위해 코드를 조합하는 동안 실수를 발견했다.


저는 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

다중 스레드를 고려하지 않음을 유의하십시오. –

관련 문제