是否有简单的方法将32位C代码编译到64位应用程序中,并进行最小的修改?该代码未设置为使用固定类型大小。简单的32位到64位转换?
我不想利用64位内存寻址。我只需要编译成一个64位的二进制文件,同时保持4个字节的长度和指针。
喜欢的东西:
#define long int32_t
当然,打破了一些长时间使用的情况下,不与指针打交道的不过。我认为这里可能有一些标准程序。
是否有简单的方法将32位C代码编译到64位应用程序中,并进行最小的修改?该代码未设置为使用固定类型大小。简单的32位到64位转换?
我不想利用64位内存寻址。我只需要编译成一个64位的二进制文件,同时保持4个字节的长度和指针。
喜欢的东西:
#define long int32_t
当然,打破了一些长时间使用的情况下,不与指针打交道的不过。我认为这里可能有一些标准程序。
似乎有成为“便携性”的两个正交的概念:
我的代码编译到处开箱。它的一般行为在所有平台上都是相同的,但可用功能的细节取决于平台的特性。
我的代码包含一个依赖于架构的东西的文件夹。无论如何,我保证MYINT32总是32位。我成功地将32位的概念移植到了火星的九指毛茸茸的lummoxes中。
在第一种方法,我们写unsigned int n;
和printf("%u", n)
,我们知道这些代码总是工作,但喜欢的unsigned int
的数值范围细节均达到了平台,而不是我们所关心的。 (Wchar_t也进来了。)这就是我所说的真正的便携式风格。
在第二种方法中,我们键入了所有内容并使用类型如uint32_t
。带有printf
的格式化输出触发了大量的警告,我们必须求助于像PRI32
这样的怪物。在这种方法中,我们从知道我们的整数总是32位宽的情况下获得了一种奇怪的权力感和控制力,但我毫不犹豫地称这种“便携式” - 它只是固执。
需要特定表示的基本概念是序列化:在一个平台上编写的文档应该在所有其他平台上可读。序列化自然是我们放弃类型系统的地方,必须担心字节序并需要决定一个固定的表示(包括文本编码等)。
的结果是这样的:
如果你坚持这一点,你甚至不必考虑你的平台是32位还是64位,大或小的端,Mac或PC,Windows或Linux。坚持标准,标准将坚持与你。
不,这通常不是可能的。考虑一下,例如,malloc()
。当它返回一个不能用32位表示的指针值时会发生什么?这个指针值怎么可能作为一个32位的值传递给你的代码,这在取消引用时可以正常工作?
这只是一个例子 - 还有很多其他类似的例子。
无论如何,编写良好的C代码本质上并不是“32位”或“64位” - 它应该在重新编译为64位二进制时无需任何修改即可正常工作。
您的实际问题是想要将32位库加载到64位应用程序中。一种方法是编写一个加载32位库的32位助手应用程序和一个加载到64位应用程序的64位匀场库。您的64位Shim库使用某种IPC机制与您的32位帮助程序进行通信,请求帮助程序代表其执行操作并返回结果。
具体案例 - 一个Matlab MEX文件 - 可能有点复杂(您需要双向函数调用,以便64位匀场库可以代表32位帮助程序执行调用,如mexGetVariable()
),但它应该仍然可行。
可能会咬你的一个区域是,如果你的32位整数中的任何一个按位进行操作。如果您假设某些状态标志存储在32位寄存器中(例如),或者如果您正在进行位移,那么您需要关注这些标志。
另一个看看的地方是任何网络代码,它假定网络上传递的整数的大小(和端)。一旦这些变为64位整数,您需要确保不会丢失符号位或精度。
包含整数的结构不再是相同的大小。任何关于尺寸和对齐的假设都需要清除。
正确编写的可移植代码将在零修改后编译和正确运行。另一方面,假设整数大小的代码可能是一个噩梦,以便移植到任何其他环境。我想我们都是在20多年前以艰辛的方式学到这一教训。 –
你在做什么平台? –
@Greg:它很容易忽略甚至隐藏编译器警告:( – pmg