2012-01-14 61 views
3

有沒有辦法讓g ++忽略或解決衝突的typedefs?在typedef C++中避免衝突的聲明錯誤

背景:

我寫了gridlab_d模擬器一些C++代碼。我的模型需要連接到一個C++數據庫,所以我使用的是mysql ++庫。使用MySQL ++的圖書館需要我鏈接到MySQL庫,所以我編譯

g++ -I/usr/include/mysql -I/usr/local/include/mysql++

問題:

的mysql.h都和list.h在gridlab的typedef一個結構有名字LIST。這是編譯器錯誤

In file included from /usr/include/mysql/mysql.h:76, 
      from /usr/include/mysql++/common.h:182, 
      from /usr/include/mysql++/connection.h:38, 
      from /usr/include/mysql++/mysql++.h:56, 
      from direct_data.cpp:21: 
/usr/include/mysql/my_list.h: At global scope: 
/usr/include/mysql/my_list.h:26: error: conflicting declaration 'typedef struct st_list LIST' 
../core/list.h:22: error: 'LIST' has a previous declaration as 'typedef struct s_list LIST' 

感謝您的幫助!

+0

你不能把'#ifndef'圍繞其中一個定義? – lapk 2012-01-14 22:13:34

+2

也許你可以創建自己的可以獨立編譯的抽象,所以這兩個typedef不會出現在同一個編譯單元中。 – 2012-01-14 22:16:31

回答

2

最好的解決辦法:

1)保持當前的主程序

EXAMPLE: "main.cpp" 

2)寫模塊爲你的數據庫訪問

EXAMPLE: dbaccess.cpp, dbaccess.h 

3)的#include「DBACCESS .h「。cpp

在dbaccess代碼中不需要任何對gridlab的引用;您不需要在dbaccess。*代碼之外引用mySql或mySQL列表。

問題解決了:)?

PS: 如果您確實需要某種可以在不同模塊之間共享的「列表」,我鼓勵您使用類似於標準C++「vector <>」的東西。恕我直言...

+0

這也是一個想法,比我的想法更清潔。 :-) – Omnifarious 2012-01-14 22:30:59

+0

如果我這樣做,我需要在dbaccess.h中包含mysql ++。h。那麼我需要在main.cpp中包含dbaccess.h。因爲main.cpp也會包含gridlab.h頭文件,所以我仍然會面臨相同的衝突聲明錯誤。我如何解決這個問題? – 2012-01-15 02:52:29

+0

不,請勿在dbaccess.h中包含mysql ++。h,僅在dbaccess.cpp中包含。關鍵是要定義你自己的原始MySQL訪問的私有抽象。 (無論如何,你的大部分代碼都不應該連接到特定的數據庫!) – 2012-01-15 16:49:14

0

我假設你在多個文件中使用SSQLS。您是否閱讀過有關在多個文件中使用SSQLS的說明?

http://tangentsoft.net/mysql++/doc/html/userman/ssqls.html#ssqls-in-header

+0

感謝您的回覆。事實證明,我沒有在多個文件中使用SSQLS。您鏈接到的部分是指爲mysql ++定義自定義SSQLS模式,我的錯誤來自於大部分庫,而我的部分沒有自定義SSQL。 – 2012-01-14 22:14:18

0

有兩種可能 - 要麼兩個列表類型是兼容的,或者他們沒有。如果它們兼容,則可以將定義複製到新的標題中,並在每個位置包含該標題。如果它們不兼容,則必須更改其中的一個名稱。

編輯:這裏是我發現做一些谷歌搜索這兩個結構定義:

的MySQL:

typedef struct st_list { 
    struct st_list *prev,*next; 
    void *data; 
} LIST; 

Gridlab:

typedef struct s_listitem { 
    void *data; 
    struct s_listitem *prev; 
    struct s_listitem *next; 
} LISTITEM; 

typedef struct s_list { 
    unsigned int size; 
    LISTITEM *first; 
    LISTITEM *last; 
} LIST; 

看着那些,好像你不會將它們按摩成同一類型。更改其中一個名字 - 或者通過大搜索/替換或者使用一些聰明的技巧 - 注意如果您選擇後一種路線,則不會犯任何錯誤。

+0

你有什麼聰明的定義技巧? :) – 2012-01-14 22:19:36

+0

@VikasYendluri - Omnifarious的答案就是一個例子。 – 2012-01-14 22:44:22

4

也許預處理器包含解決您的問題。

#define LIST GRIDLAB_LIST 
#include <gridlab_include_file.h> 
#undef LIST 

這當然依賴於gridlab而不是#include任何來自MySQL的東西。

+0

有趣,這是如何工作的? – 2012-01-14 22:19:27

+0

@VikasYendluri - 它基本上使得預處理器在出現'LIST'的每個地方都用'GRIDLAB_LIST'對'LIST'進行簡單的文本替換。由於'LIST'是一個typedef,因此在結果對象文件中不可能提及(即使使用C++)這個名字。它不會導致編譯或鏈接問題。 – Omnifarious 2012-01-14 22:22:23

+0

除非有需要使用兩種列表類型的代碼,否則這是一個好的開始。實際上 - 只要您在共享代碼的正確位置使用GRIDLAB_LIST,即使這樣也行。 – 2012-01-14 22:44:59