2012-01-14 229 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