在dll界面上枚举的问题? [英] Problems with enums across a dll interface?

查看:79
本文介绍了在dll界面上枚举的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我最近与一位同事讨论了如何在

dll界面中使用枚举。他想使用字符代替,争辩说,根据

编译器设置,枚举的大小可能会改变并导致内存损坏。我没看到这是怎么可能的。他声称,如果为程序构建的dll

使用与

启动程序不同的编译器设置构建,则枚举大小可能会发生变化。

我唯一想弄清楚这个的方法就是将字节

对齐更改为1或2.然后从dll读取数据结构中的一个字节

a时间假设你知道内存是如何布局的那样。

那么对齐可能会改变枚举所在的位置你可以

读错了记忆。


这个问题的唯一症状是,当启动器应用程序退出时,机器会重新启动。我相信这是一个运行VC 6.0的98系统。

对我而言,这听起来更像是内存被不正确的指针所破坏

管理。这听起来是否有可能。以任何方式使用枚举是否有点不安全

?我希望不会或我的世界崩溃。


SpaceCowboy

[见 http://www.gotw.ca/resources/clcm.htm 有关的信息]

[comp.lang .C ++。主持。第一次海报:做到这一点! ]


[comp.std.c ++被审核。要提交文章,请尝试发布]

[您的新闻阅读器。如果失败,请使用mailto:st ***** @ ncar.ucar.edu]

[---请在发布前查看常见问题解答。 ---]

[常见问题: http://www.jamesd.demon.co.uk/csc/faq.html ]


I recently got into a discussion with a co-worker about using enums across a
dll interface. He wanted to use chars instead, argueing that depending on
compiler settings the size of an enum could change and lead to memory
corruption. I didn''t see how this was possible. He claims that if a dll
built for a program is built with different compiler settings than the
launcher program, the enum size could change.

The only way I could figure out to break this would be change the byte
alignment to 1 or 2. Then read in the data structure from the dll a byte at
a time assuming all the while that you knew how the memory was laid out.
Then the alignment could change where the enum was located and you could
read bad memory.

The only symptom of this problem is that when the launcher application is
exited, the machine reboots. I believe it is a 98 system running VC 6.0.
To me this sounds more like memory being trashed by improper pointer
management. Does any of this sound remotely possible. Is it somehow unsafe
to use enums in any way? I hope not or my world will fall apart.

SpaceCowboy
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

推荐答案



Hi SpaceCowboy,


" SpaceCowboy" < BL *** @ hotmail.com> schrieb im Newsbeitrag

新闻:2F ******************* @ twister.austin.rr.com ..

Hi SpaceCowboy,

"SpaceCowboy" <bl***@hotmail.com> schrieb im Newsbeitrag
news:2F*******************@twister.austin.rr.com.. .

我最近与一位同事讨论了在
a dll界面中使用枚举的问题。他想改用chars,争辩说依赖于编译器设置,枚举的大小可能会改变并导致内存损坏。我没看到这是怎么可能的。他声称,如果为程序构建的dll是使用与
启动程序不同的编译器设置构建的,则枚举大小可能会改变。

I recently got into a discussion with a co-worker about using enums across a dll interface. He wanted to use chars instead, argueing that depending on
compiler settings the size of an enum could change and lead to memory
corruption. I didn''t see how this was possible. He claims that if a dll
built for a program is built with different compiler settings than the
launcher program, the enum size could change.




所有C或C ++数据类型的大小都依赖于编译器(即使是
依赖于编译器选项!)。


因此,为了保持DLL之间的一致性,你应该就具体的

类型达成一致。如果您的应用程序仅在Windows上运行,您可以使用

预定义的固定长度类型,如BYTE,WORD或DWORD。不要使用INT或

int,因为它会根据你是在写一个16位,32位还是64位的b $ b b应用而改变。


没有指定枚举类型的大小。编译器可以使它们成为可能的最小尺寸,int或其他东西。


其他类型的大小定义为sizeof(char )< =

sizeof(短)< = sizeof(int)< = sizeof(long)。如果你使用这些类型,你需要使用b $ b使自己依赖于编译器。通常的解决方法是使用

额外包含文件来定义类型,例如int8_t,int16_t,int32_t,/ b $ b和int64_t,或类似的。这样你就不得不在编译器改变的情况下只更改包含文件




我希望有所帮助。


问候,

Ekkehard Morgenstern。



The size of all C or C++ datatypes are compiler-dependent (even
compiler-option dependent!).

So, to maintain consistency across DLLs, you should agree on a specific
type. If your application is to be run only on Windows, you can use
predefined fixed-length types like BYTE, WORD or DWORD. Don''t use INT or
int, since it changes depending whether you''re writing a 16-,32- or 64-bit
application.

The size of enum types isn''t specified. The compiler can either make them
the smallest size possible, int, or something else.

The size of the other types is defined such that sizeof(char) <=
sizeof(short) <= sizeof(int) <= sizeof(long). If you use these types, you
make yourself dependent on the compiler. The usual workaround is to have an
extra include file for defining types like "int8_t", "int16_t", "int32_t"
and "int64_t", or similar. This way you have to change only the include file
in case the compiler changes.

I hope that helps.

Regards,
Ekkehard Morgenstern.


SpaceCowboy写道:
SpaceCowboy wrote:

我最近与一位同事讨论了如何在一个dll界面上使用枚举。他想改用chars,争辩说依赖于编译器设置,枚举的大小可能会改变并导致内存损坏。我没看到这是怎么可能的。他声称,如果为程序构建的dll是使用与
启动程序不同的编译器设置构建的,则枚举大小可能会发生变化。


这是正确的。但是,这不是唯一可以改变的东西。

非常非常警惕用不同的

编译器设置编译不同的源文件(虽然它通常是安全的有不同的

优化设置)。


< snip>此问题的唯一症状是当退出启动器应用程序时,机器重新启动。我相信它是一个运行VC 6.0的98系统。


据我所知,虽然在其他一些编译器中也没有设置可以改变Visual C ++中

枚举对象的大小。


这里是Visual C ++ 6.0的设置列表,如果它们在各种翻译单元之间有所不同,可能导致

不兼容

可执行模块。它可能不完整。


- 预处理器定义和标题路径,如果它们导致包含不同的

定义

- 指向成员的代表

- 启用/禁用异常处理

- 启用/禁用RTTI

- 启用/禁用构造位移
- 运行时库变体

- 调用约定

- struct member alignment


另请注意不同虽然Windows C ++编译器供应商通常会尝试使用与某些版本的Visual C ++兼容的代码来生成代码,但C ++编译器通常不会产生与b $ b兼容的代码。

对我而言,这听起来更像是由于指针管理不当而导致的内存被破坏。这听起来是否有可能。


也许。一个人永远不会知道,使用Windows 98.在Windows NT中尝试一下

(注意,2000和XP是NT的更高版本)因为它更有可能是
陷阱这样的错误。

以任何方式使用枚举是否有些不安全?我希望不会或我的
世界崩溃。

I recently got into a discussion with a co-worker about using enums across
a dll interface. He wanted to use chars instead, argueing that depending
on compiler settings the size of an enum could change and lead to memory
corruption. I didn''t see how this was possible. He claims that if a dll
built for a program is built with different compiler settings than the
launcher program, the enum size could change.
This is correct. However, this is not the only thing that could change.
Be very, very wary of compiling different source files with different
compiler settings (though it''s normally safe to have different
optimisation settings).

<snip> The only symptom of this problem is that when the launcher application is
exited, the machine reboots. I believe it is a 98 system running VC 6.0.
So far as I know, there are no settings that would change the size of
enum objects in Visual C++, though there are in some other compilers.

Here''s a list of settings for Visual C++ 6.0 that can cause
incompatibility if they differ between the various translation units and
executable modules. It might not be complete.

- preprocessor definitions and header paths, if they cause different
definitions to be included
- pointer-to-member representation
- exception handling enabled/disabled
- RTTI enabled/disabled
- construction displacements enabled/disabled
- run-time library variant
- calling convention
- struct member alignment

Also note that different C++ compilers don''t generally produce
compatible code, though the Windows C++ compiler vendors generally try
to produce code that''s compatible with some version of Visual C++.
To me this sounds more like memory being trashed by improper pointer
management. Does any of this sound remotely possible.
Maybe. One never knows, with Windows 98. Try it out in Windows NT
(note, 2000 and XP are later versions of NT) as it is more likely to
trap such bugs.
Is it somehow unsafe to use enums in any way? I hope not or my
world will fall apart.




添加枚举器时需要小心。严格来说,对共享定义进行任何更改后,您应该重建每个文件
使用它们的
(一个定义规则)。在实践中,只要(1)你没有改变任何现有的价值

,就可以安全地添加枚举器,并且( 2)任何检查枚举的

值的代码都是为了能够处理无法识别的值而编写的。对于

的例子,如果你有:


enum blah

{

AARDVARK,

ABACUS,

ADVERB

};


您将其更改为:


enum blah

{

AARDVARK,

ABACUS,

ACTOR,

ADVERB

};


然后ADVERB的数值从2变为3.这将是

打破与使用旧定义编译的任何代码的兼容性。

但是,如果您在枚举结束时添加ACTOR,那么

现有枚举器将保留其旧值,并且更改

应该是安全的。


请注意,枚举类型的基础整数类型

取决于值其成员,所以你必须避免添加一个需要更改类型的

枚举器。只要你的

枚举器都小到可以用char代表,这个

应该不是问题。


[见 http://www.gotw.ca/resources/clcm。 htm 有关的信息]

[comp.lang.c ++。moderated。第一次海报:做到这一点! ]



You need to be careful when adding enumerators. Strictly speaking,
after any change to shared definitions you should rebuild every file
that uses them (the One Definition Rule). In practice it''s generally
safe to add enumerators as long as (1) you don''t change the value of
any of the existing ones, and (2) any code that checks an enumerated
value is written to be able to cope with unrecognised values. For
example, if you have:

enum blah
{
AARDVARK,
ABACUS,
ADVERB
};

and you change it to be:

enum blah
{
AARDVARK,
ABACUS,
ACTOR,
ADVERB
};

then the numeric value of ADVERB changes from 2 to 3. This will
break compatibility with any code compiled with the old definition.
However, if you add ACTOR at the end of the enumeration then the
existing enumerators will keep their old values, and the change
should be safe.

Note that the underlying integer type of an enumerated type
depends on the values of its members, so you must avoid adding an
enumerator that would require a change of type. So long as your
enumerators are all small enough to be represented by a char this
shouldn''t be an issue.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]





嗨SpaceCowboy,


" SpaceCowboy" < BL *** @ hotmail.com> schrieb im Newsbeitrag

新闻:2F ******************* @ twister.austin.rr.com ..


Hi SpaceCowboy,

"SpaceCowboy" <bl***@hotmail.com> schrieb im Newsbeitrag
news:2F*******************@twister.austin.rr.com.. .

我最近与一位同事讨论了在
a dll界面中使用枚举的问题。他想改用chars,争辩说依赖于编译器设置,枚举的大小可能会改变并导致内存损坏。我没看到这是怎么可能的。他声称,如果为程序构建的dll是使用与
启动程序不同的编译器设置构建的,则枚举大小可能会改变。

I recently got into a discussion with a co-worker about using enums across a dll interface. He wanted to use chars instead, argueing that depending on
compiler settings the size of an enum could change and lead to memory
corruption. I didn''t see how this was possible. He claims that if a dll
built for a program is built with different compiler settings than the
launcher program, the enum size could change.




所有C或C ++数据类型的大小都依赖于编译器(即使是
依赖于编译器选项!)。


因此,为了保持DLL之间的一致性,你应该就具体的

类型达成一致。如果您的应用程序仅在Windows上运行,您可以使用

预定义的固定长度类型,如BYTE,WORD或DWORD。不要使用INT或

int,因为它会根据你是在写一个16位,32位还是64位的b $ b b应用而改变。


没有指定枚举类型的大小。编译器可以使它们成为可能的最小尺寸,int或其他东西。


其他类型的大小定义为sizeof(char )< =

sizeof(短)< = sizeof(int)< = sizeof(long)。如果你使用这些类型,你需要使用b $ b使自己依赖于编译器。通常的解决方法是使用

额外包含文件来定义类型,例如int8_t,int16_t,int32_t,/ b $ b和int64_t,或类似的。这样你就不得不在编译器改变的情况下只更改包含文件




我希望有所帮助。


问候,

Ekkehard Morgenstern。


[见 http://www.gotw.ca/resources/clcm.htm 有关的信息]

[comp.lang.c ++。主持。第一次海报:做到这一点! ]


[comp.std.c ++被审核。要提交文章,请尝试发布]

[您的新闻阅读器。如果失败,请使用mailto:st ***** @ ncar.ucar.edu]

[---请在发布前查看常见问题解答。 ---]

[常见问题: http://www.jamesd.demon.co.uk/csc/faq.html ]



The size of all C or C++ datatypes are compiler-dependent (even
compiler-option dependent!).

So, to maintain consistency across DLLs, you should agree on a specific
type. If your application is to be run only on Windows, you can use
predefined fixed-length types like BYTE, WORD or DWORD. Don''t use INT or
int, since it changes depending whether you''re writing a 16-,32- or 64-bit
application.

The size of enum types isn''t specified. The compiler can either make them
the smallest size possible, int, or something else.

The size of the other types is defined such that sizeof(char) <=
sizeof(short) <= sizeof(int) <= sizeof(long). If you use these types, you
make yourself dependent on the compiler. The usual workaround is to have an
extra include file for defining types like "int8_t", "int16_t", "int32_t"
and "int64_t", or similar. This way you have to change only the include file
in case the compiler changes.

I hope that helps.

Regards,
Ekkehard Morgenstern.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


这篇关于在dll界面上枚举的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆