2016-06-08 1 views
0

나는 UINode라고 불리는 GUI를 가지고 있는데, 복제물을 만들고 몇 가지를 바꾸고 싶다. 프로젝트는 3 개의 기본 스레드로 구성됩니다. PingThread, RosThread 및 GuiThread가 있습니다. 프로젝트 폴더를 복사하여 붙여 넣으려고하고 UINode2로 이름을 바꾸려고했지만 catkin_make를 사용하여 컴파일하려고하면 오류가 발생합니다. 나는 이것이 동일한 헤더로 인한 오류라고 확신한다.C++ Qt 작은 변화로 GUI 복제본을 만드는 방법

오류 :

CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x0): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o:(.rodata+0x100): multiple definition of `tum_ardrone_gui::staticMetaObject' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:(.rodata+0x100): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o: In function `tum_ardrone_gui::qt_metacast(char const*)': moc_tum_ardrone_gui.cxx:(.text+0x20): multiple definition of `tum_ardrone_gui::qt_metacast(char const*)' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x20): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o: In function `tum_ardrone_gui::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)': moc_tum_ardrone_gui.cxx:(.text+0x70): multiple definition of `tum_ardrone_gui::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x70): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o: In function `tum_ardrone_gui::qt_metacall(QMetaObject::Call, int, void**)': moc_tum_ardrone_gui.cxx:(.text+0x6f0): multiple definition of `tum_ardrone_gui::qt_metacall(QMetaObject::Call, int, void**)' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x6f0): first defined here 

코드 :

#include "tum_ardrone_gui.h" 
#include "RosThread.h" 
#include "PingThread.h" 

#include <QtGui> 
#include <QApplication> 
#include "ros/ros.h" 

// this global var is used in getMS(ros::Time t) to convert to a consistent integer timestamp used internally pretty much everywhere. 
// kind of an artifact from Windows-Version, where only that was available/used. 
unsigned int ros_header_timestamp_base = 0; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Starting drone_gui Node" << std::endl; 

    // ROS 
    ros::init(argc, argv, "drone_gui"); 

    RosThread t; 
    PingThread p; 

    // UI 
    QApplication a(argc, argv); 
    tum_ardrone_gui w; 

    // make them communicate with each other 
    t.gui = &w; 
    w.rosThread = &t; 
    p.gui = &w; 
    p.rosThread = &t; 
    w.pingThread = &p; 

    // start them. 
    t.startSystem(); 
    p.startSystem(); 
    w.show(); 

    // wait until windows closed.... 
    int ec = a.exec(); 

    // stop ROS again.... 
    t.stopSystem(); 
    p.stopSystem(); 

    std::cout << "Exiting drone_gui Node" << std::endl; 

    return ec; 
} 

내 질문 : 내 UINode 10 번 복제 할 상상해보십시오. 내 코드를 하드 코딩하고 모든 스레드 이름, 클래스 등을 변경해야합니까? 아니면 더 좋은 방법이 있습니까?

+1

다른 프로젝트를하고 있습니까? 아니면 동일한 프로젝트에서 다른 노드를 만들고 싶습니까? – coyotte508

+0

그들은 구독하고 게시 할 각 노드 (Robot1 및 Robot2)의 경로를 변경해야하기 때문에 서로 다른 프로젝트 여야합니다. 하지만 UINode2와 함께 Robot1을 제어하고 동시에 UINode2를 사용하여 Robot2를 제어하기 위해 동시에 컴파일하고 실행하려고합니다. –

+0

'각 노드의 경로'란 정확히 무엇을 의미합니까? 파일 시스템 에서요? 명령 줄 매개 변수를 통해 응용 프로그램에 전달할 수 있습니까? 그럼 당신은 단지 추가 응용 프로그램을 전혀 만들지 않아도 이들을 평가해야 할 것입니다 ... – Aconcagua

답변

2

별도의 프로젝트에서 공통적 인 코드를 모두 수집하여 라이브러리 (정적 또는 공유)로 빌드하는 것이 좋습니다. 차이를 다형성으로 구현하는 것이 편리 할 수 ​​있으므로 라이브러리에 기본 클래스가 있고 특정 프로젝트의 하위 클래스에서 동작을 구현하거나 무시할 수 있습니다.

이렇게하면 각 프로젝트의 차이점 만 구현하고 모든 코드를 공통 코드가 포함 된 라이브러리에 연결합니다.

편집 :

아마 모든 일이 필요하지 않습니다 : 당신이 명령 줄 매개 변수를 통해 응용 프로그램의 각 인스턴스에 다른 행동을 제어하는 ​​생각이 있나요?

어떤 용도로든 TCP 클라이언트가 있다고 가정 해보십시오. 통신하려는 새 호스트마다 사용을 위해 다시 컴파일 하시겠습니까? 확실히. 대신 매개 변수로 호스트 주소를 전달합니다 (예 : 지. -h 127.0.0.1 -p 1977 또는 -h 127.0.0.1:1977.

+0

저는 begineer : D 당신은 단순화 할 수 있습니까? –

+0

라이브러리는 서로 다른 실행 파일에서 하나의 동일한 코드를 공유하도록 설계되었습니다. 장점은 한 번 컴파일 된 것이므로 이미 완성 된 코드를 원하는 수의 응용 프로그램에 포함시킬 수 있다는 것입니다 (기술적으로는 정확합니다. 혹시 gcc의 -l 옵션을 발견 한 적이 있습니까? (나는 msvc와 동일하다고 생각합니다.) 이 옵션을 사용하면 예를 들어 QT GUI 응용 프로그램을 빌드하는 경우 라이브러리에서 제공되는 이미 컴파일 된 코드를 사용 (링크)합니다. – Aconcagua

+0

동의합니다. 이것이 바로 리팩토링입니다. 그러나 다형성은 그것을 성취 할 수있는 유일한 방법은 아닙니다. – user2672165