- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在将我的应用程序(win32 和 MFC 的混合体)移植到 Visual Studio 2017 (x64) 使用 VC98(使用命令行上的 makefile 构建,而不是 IDE)(x86) 编译。该应用程序使用了大量的 C 结构,这些结构与数据一起打包,复制到缓冲区并通过 N/W 发送。通信协议(protocol)要求这些结构完全没有额外的填充,以便发送的数据符合用于客户端(我的应用程序)和服务器的通信规范。为确保这一点,应用程序使用/Zp 来编译每个文件。
在使用/Zp(从 IDE)移植到 VS2017 (x64) 后,当我尝试运行应用程序时,应用程序 GUI 没有启动,并且当某些 SDK/MFC 定义的结构是由应用程序访问,例如 OPENFILENAME。因此,为了解决这个问题,在 VS2017 中仍然在项目级别定义/Zp 的情况下,我在包含 windows.h 的地方使用了以下内容:
#ifdef _WIN64
#pragma pack(push,8)
#endif
#include <windows.h>
#ifdef _WIN64
#pragma pack(pop)
#endif
这在一定程度上解决了这个问题,但我仍然从 MFC 中得到一些错误,一些功能如 crypt API (MSCAPI) 不起作用,这可能是因为我的应用程序包含其他头文件,如 windows.h,它们也需要像上面一样受到保护。
作为替代方案,我也尝试过完全不使用/Zp,然后转到每个头文件并将文件的全部内容(在系统头文件包含之后)包含在 #pragma pack(1) 之间和#pragma pack()。这可行,但并非万无一失,而且对我来说对 1000 个头文件做同样的事情太乏味了。
因此,简而言之,我需要一种方法来确保我的应用程序定义的所有 C 结构不使用任何填充,但 Windows SDK/MFC 定义的结构继续使用默认填充(可能是 8 个字节)。关于如何以最少的更改以万无一失的方式解决此问题的任何想法?也许,这个问题不会出现在 VC98 中,因为平台是 x86,或者 VC98 附带的 SDK 没有对结构的打包做出任何假设。
最佳答案
通过网络或通过文件传输二进制结构数据是一种非常脆弱的方法:
struct
定义中使用的类型保持相同的表示形式,打包结构只能解决对齐问题。检查结构中使用的低级类型的定义:LONG
在 64 位 Windows (!) 上仍然是 32 位的,但 size_t
具有不同的大小。为了解决这些可移植性问题,现代程序不依赖于二进制数据的内部表示,它们一次处理一个成员的结构化数据,以在两端使用特定的表示、大小、字节顺序、位编码。
关于c - 如何使用#pragma pack(1) OR/Zp1 以便它们单独影响应用程序定义结构的打包,而不影响 Windows SDK 中定义的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55682637/
我是一名优秀的程序员,十分优秀!