2011-06-29 224 views
4

是否有简单的方法将32位C代码编译到64位应用程序中,并进行最小的修改?该代码未设置为使用固定类型大小。简单的32位到64位转换?

我不想利用64位内存寻址。我只需要编译成一个64位的二进制文件,同时保持4个字节的长度和指针。

喜欢的东西:

#define long int32_t 

当然,打破了一些长时间使用的情况下,不与指针打交道的不过。我认为这里可能有一些标准程序。

+11

正确编写的可移植代码将在零修改后编译和正确运行。另一方面,假设整数大小的代码可能是一个噩梦,以便移植到任何其他环境。我想我们都是在20多年前以艰辛的方式学到这一教训。 –

+1

你在做什么平台? –

+0

@Greg:它很容易忽略甚至隐藏编译器警告:( – pmg

回答

3

似乎有成为“便携性”的两个正交的概念:

  1. 我的代码编译到处开箱。它的一般行为在所有平台上都是相同的,但可用功能的细节取决于平台的特性。

  2. 我的代码包含一个依赖于架构的东西的文件夹。无论如何,我保证MYINT32总是32位。我成功地将32位的概念移植到了火星的九指毛茸茸的lummoxes中。

在第一种方法,我们写unsigned int n;printf("%u", n),我们知道这些代码总是工作,但喜欢的unsigned int的数值范围细节均达到了平台,而不是我们所关心的。 (Wchar_t也进来了。)这就是我所说的真正的便携式风格。

在第二种方法中,我们键入了所有内容并使用类型如uint32_t。带有printf的格式化输出触发了大量的警告,我们必须求助于像PRI32这样的怪物。在这种方法中,我们从知道我们的整数总是32位宽的情况下获得了一种奇怪的权力感和控制力,但我毫不犹豫地称这种“便携式” - 它只是固执。

需要特定表示的基本概念是序列化:在一个平台上编写的文档应该在所有其他平台上可读。序列化自然是我们放弃类型系统的地方,必须担心字节序并需要决定一个固定的表示(包括文本编码等)。

的结果是这样的:

  • 使用标准语言基本编写自己的主程序核心便携的风格。
  • 编写良好定义的干净的I/O接口用于序列化。

如果你坚持这一点,你甚至不必考虑你的平台是32位还是64位,大或小的端,Mac或PC,Windows或Linux。坚持标准,标准将坚持与你。

2

不,这通常不是可能的。考虑一下,例如,malloc()。当它返回一个不能用32位表示的指针值时会发生什么?这个指针值怎么可能作为一个32位的值传递给你的代码,这在取消引用时可以正常工作?

这只是一个例子 - 还有很多其他类似的例子。

无论如何,编写良好的C代码本质上并不是“32位”或“64位” - 它应该在重新编译为64位二进制时无需任何修改即可正常工作。


您的实际问题是想要将32位库加载到64位应用程序中。一种方法是编写一个加载32位库的32位助手应用程序和一个加载到64位应用程序的64位匀场库。您的64位Shim库使用某种IPC机制与您的32位帮助程序进行通信,请求帮助程序代表其执行操作并返回结果。

具体案例 - 一个Matlab MEX文件 - 可能有点复杂(您需要双向函数调用,以便64位匀场库可以代表32位帮助程序执行调用,如mexGetVariable()),但它应该仍然可行。

+0

我想可能有一些兼容性层,你可以用malloc替换malloc只返回32位指针。 – Jim

+0

@Mark:兼容性层是在64位系统上运行32位二进制文​​件时获得的。如果这就是你想要的,那就继续编译32位二进制文​​件。 – caf

+0

不幸的是我需要二进制为64位才能被另一个64位应用程序加载。这是一个matlab mex文件。 – Jim

0

可能会咬你的一个区域是,如果你的32位整数中的任何一个按位进行操作。如果您假设某些状态标志存储在32位寄存器中(例如),或者如果您正在进行位移,那么您需要关注这些标志。

另一个看看的地方是任何网络代码,它假定网络上传递的整数的大小(和端)。一旦这些变为64位整数,您需要确保不会丢失符号位或精度。

包含整数的结构不再是相同的大小。任何关于尺寸和对齐的假设都需要清除。