2016-11-18 3 views
1

각 dll에서 각기 다른 클래스 구현을 사용하는 시스템을 만들려고합니다. 그래서 한 구현 및 개인 메서드 (및 아마도 그 DLL에 의해 엄격하게 사용되는 메서드) VertexBufferObject 클래스를 가질 것이다. 그러나 특정 실행 파일 집합 만이 주요 실행 파일에 사용됩니다.여러 DLL에서 클래스 구현이 개별적으로 구현됩니다.

openglGraphics.dll에서 : directXGraphics.dll에서

class VertexBufferObject { 
    private: 
     // Unexported data 
     uint vbo; 

     // Exported data (won't actually use this though) 
     std::vector<Vec3> arr; 
    public: 
     // Unexported methods 
     IDirect3DVertexBuffer9 *getVBO(); 

     // Exported methods 
     virtual void Build(Vec2 array); 
     virtual void Build(Vec3 array); 
     virtual void Unbind(); 
     ~VertexBufferObject(); 
}; 

예를 들어

class VertexBufferObject { 
    private: 
     // Unexported data 
     IDirect3DVertexBuffer9 vbo; 

     // Exported data (won't actually use this though) 
     std::vector<Vec3> arr; 
    public: 
     // Unexported methods 
     IDirect3DVertexBuffer9 *getVBO(); 

     // Exported methods 
     virtual void Build(Vec2 array); 
     virtual void Build(Vec3 array); 
     virtual void Unbind(); 
     ~VertexBufferObject(); 
}; 

그리고 마지막으로, 실행은 공장 기능을 사용하여 클래스의 수출 방법을 만들 수는 없지만 dll 특정 메서드. 이것이 가능한가? 그것을 처리 할 다른 방법이 있습니까? (또한 그래픽 API를 사용하고 있으면 멋진 점을 발견 할 수 있지만 질문의 요지는 찾을 수 없습니다.)

+2

인터페이스를 사용하여 공용 API를 나타냅니다. –

답변

1

DLL 측에서 확실히 가능합니다. 귀하의 구현은 별도의 컴파일 단위와 별도의 DLL 및 심지어 별도의 프로젝트에있을 것입니다. 하지만 ...

클라이언트가 개체의 정의를 알아야하고 ODR 규칙에 정의가 하나만 있어야하므로 DLL 클라이언트 측에서 작동하지 않습니다.

그래서 수정 된 디자인과 지속 가능한 디자인을 선택하는 것이 좋습니다.

옵션 1 : openglGraphics.dll에서 공용 인터페이스

class IVertexBuffer { 
    public: 
     // Exported methods 
     virtual void Build(Vec2 array)=0; 
     virtual void Build(Vec3 array)=0; 
     virtual void Unbind()=0; 
     virtual ~IVertexBuffer();  // virtual function ==> virtual dtor !!! 
}; 

사용 상속 :

class VertexBufferGLObject : public IVertexBuffer { 
    private: 
     uint vbo; 
     std::vector<Vec3> arr; 
    public: 
     // Unexported methods 
     IDirect3DVertexBuffer9 *getVBO(); 

     // Exported methods of the interface 
     void Build(Vec2 array) override; 
     void Build(Vec3 array) override; 
     void Unbind() override; 
     ~VertexBufferObject(); 
}; 

VertexBufferGLObject을 소프트웨어 구성에 따라 올바른 DLL을로드하고 만들 수 팩토리 클라이언트 코드는 다형 기본 클래스 만 사용합니다.

그러나 클라이언트 코드는 포인터와 참조 만 사용한다는 의미입니다. 복사가 필요한 경우 슬라이싱의 위험을 피하려면 clone() 함수를 사용해야합니다.

옵션 2 : 또한 PIMPL idiom라고도 compilation firewall를 사용할 수있는 내부 구조

을 숨기고 더 많은 유연성을 제공합니다.

class IVertexBufferImpl; // you need to define this only in the implementation 
class VertexBufferObject { 
    private: 
     IVertexBufferImpl *myobject; 
    public: 
     // Exported methods 
     virtual void Build(Vec2 array); 
     virtual void Build(Vec3 array); 
     virtual void Unbind(); 
     virtual ~VertexBufferObject(); 
     // + rule of 3 
}; 

좀 더 간접적 인 수준이 :

아이디어는 다음과 같다. 그러나이 클래스의 구현은 IVertexBuffer 객체에 대한 호출을 전달할 것이고, 옵션 1에서와 같이 팩토리를 사용하여 private 객체를 생성 할 수 있습니다. 이점은 클라이언트가 다른 객체로서 VertexBufferObject를 사용할 수 있다는 것입니다 (값 또는 참조로).) : 그것은 캡슐화/격리에서 더 한 단계의 것입니다.

옵션 3 : 사용 구현에서 추상화를 감에서 다리 디자인 패턴

bride design pattern 것을 목표로하고있다.

옵션 2는 작동 방식이 비슷하지만 의도는 다릅니다. 목표는 구현을 숨기지 않고 양면의 파생 및 정제를 피하기 위해 분리를 수행하는 것입니다. 추상화 및 켜기 구현 측면.

+0

고마워요! 브릿지 패턴 시스템은 너무 복잡해 보이고 필요한 것보다 더 많은 호출을합니다. 속도가 중요하므로 함수 호출 수를 제한하고 데이터를 지역화하며 메모리를 제한하려고합니다. 속도면에서 볼 때 옵션 2가 가장 좋을 것 같습니다. 다시 한번 감사드립니다. –

관련 문제