如何通过 Haskell FFI 获取 C 全局变量的地址?

How do I get the address of a C global variable through the Haskell FFI?

例如,在 C 中,我声明了这样的内容:

extern char _binary_res_txt_start[];

它来自这个命令:

ld -r -b binary -o binary.o res.txt

如何在 Haskell 中获得指向那里的 Ptr?如果它是一个函数,我会做类似 foreign import ccall "&exp" a_exp :: FunPtr (Double -> Double) 的事情,但我认为这不适用于变量。

只要您使用 &foreign import 语法也适用于变量。如果它不是以 null 结尾但您知道它的长度,则可以使用 peekCString or packCString to read it (or peekCStringLen or packCStringLen。这是一个完整的例子:

printf 'foo[=10=]bar' > res.txt
ld -r -b binary -o binary.o res.txt
extern char _binary_res_txt_start[];
extern char _binary_res_txt_end[];
import Foreign.C.Types
import Foreign.C.String
import Foreign.Ptr

foreign import ccall "&_binary_res_txt_start" txt_start :: Ptr CChar
foreign import ccall "&_binary_res_txt_end" txt_end :: Ptr CChar

main = do
  str <- peekCStringLen (txt_start, txt_end `minusPtr` txt_start)
  print str
"foo\NULbar"

请注意,虽然 ld -b binary 也会生成一个 _binary_res_txt_size 符号,但现在 ASLR 已成为现实,它不再有用了。有关详细信息,请参阅