2017-04-12 417 views
2

这是一个很长的画面,但我想知道是否有任何技巧可以在编译时间将常量ipv6地址字符串转换为两个64位整数。 (这是嵌入式系统,因此运行时和内存都是有价值的商品)。理想情况下,代码会看起来像:c:在编译时将ipv6地址转换为字符串

const uint64_t addr[2] = { IPV6_TO_UINT64S("::ffff:192.168.1.1") }; 

这将产生:

const uint64_t addr[2] = { 0x0000000000000000ULL, 0x0000ffffc0a80101ULL }; 
+3

我会写另一个用来预处理源代码的程序。 – Barmar

+0

沿着同样的路线,我建议你把这些IPv6常量放在一个JSON配置文件中,然后写一个模板头文件。使用程序来处理常量并填写模板中的空白。使用你喜欢的任何编程语言和模板系统。 – Schwern

+0

你可以在*编码*时间做到这一点。这可能是通过代码生成器,或通过您似乎已执行的手动计算。 –

回答

1

对于这样的事情,我建议写一个模板头文件(不是C++模板,但填写在 - 空白模板),将人类可读的值放入配置文件中,并使用小程序填充空白。

例如,配置文件可能是JSON。 (这显然是矫枉过正了一个值,我只是显示技术)。

{ 
    "addr": "::ffff:192.168.1.1" 
} 

你可以使用现有的模板语言,或弥补自己。对于像C头文件这样简单的东西,你可以放弃一些非常简单的事情。

const uint64_t addr[2] = { %%addr%% }; 

而代码读取的配置和处理模板简单的普遍的脚本语言,如Ruby。

#!/usr/bin/env ruby 

require 'json' 

template, config_file = ARGV[0..1] 

# Load the config file 
config = JSON.load(File.new(config_file)) 

# Ensure missing config variables throw an error 
config.default_proc = proc do |hash, key| 
    throw "Config key '#{key}' is missing from #{config_file}" 
end 

# ...do whatever processing on the config variables you want... 

# Fill in the template. 
IO.foreach(template) { |line| 
    puts line.gsub(/%%(.*?)%%/) { config[$1] } 
} 

我在y2038库中使用了这种技术。它必须探测系统以确定time.h的限制,然后将这些限制编码到自定义头文件中。 munge_config读取配置值(来自构建系统,而不是来自JSON配置,但结果相同:散列),并填充模板。这是time64_limits.h.in templatea resulting time64_limits.h header file的一个例子。

+0

感谢您的答复,但同时这也是有趣的,我的目的,它的速度更快,更方便到位,更新地址(我的主要目标之一是可读性)。 – blackghost

+0

@John您可以添加原始值作为评论。 – Schwern