2017-04-12 63 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

相關問題