簡體   English   中英

如何使用 Haskell 的 FunPtr?

[英]How do I use a FunPtr from Haskell?

假設有以下文件:

測試2.h:

typedef int (*signature) ();

extern const signature lol2;

測試2.c:

#include "test2.h"

int lol() {
  return 42;
}

const signature lol2 = lol;

測試2.hs:

module Main where

import Foreign.C
import Foreign.Ptr

type Fun =
  IO CInt

foreign import ccall
  "test2.h lol2"
  fun_ptr
  :: FunPtr Fun

foreign import ccall "dynamic" mkFun :: FunPtr Fun -> Fun

lol = mkFun fun_ptr

main = do
  fortytwo <- lol
  putStrLn $ show $ fortytwo

使用以下編譯:

gcc -shared test2.c -Wall -Wextra -o libtest2.so -g3 -ggdb3
ghc -o test2 Test2.hs -ltest2 -optl-Wl,-rpath,. -L. -g

(GHC 在 lol2 聲明之前發出關於缺少“&”的警告,但我認為警告是錯誤的,所以我忽略它。另外,請注意我沒有使用-dynamic 。如果我這樣做,結果是一樣的)

但是,我在運行時得到一個 SIGSEGV:

(gdb) break scheduleWaitThread
Breakpoint 1 at 0x468150: file rts/Schedule.c, line 2509.
(gdb) r
Starting program: [...]/test2 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, scheduleWaitThread (tso=0x4200105388, ret=ret@entry=0x0, pcap=pcap@entry=0x7fffffffd7f8) at rts/Schedule.c:2509
2509    rts/Schedule.c: No such file or directory.
(gdb) bt
#0  scheduleWaitThread (tso=0x4200105388, ret=ret@entry=0x0, pcap=pcap@entry=0x7fffffffd7f8) at rts/Schedule.c:2509
#1  0x0000000000483864 in rts_evalLazyIO (cap=cap@entry=0x7fffffffd7f8, p=p@entry=0x4a5420, ret=ret@entry=0x0) at rts/RtsAPI.c:530
#2  0x00000000004707ae in hs_main (argc=1, argv=0x7fffffffd9e8, main_closure=0x4a5420, rts_config=...) at rts/RtsMain.c:72
#3  0x0000000000406b46 in main ()
(gdb) finish
Run till exit from #0  scheduleWaitThread (tso=0x4200105388, ret=ret@entry=0x0, pcap=pcap@entry=0x7fffffffd7f8) at rts/Schedule.c:2509

Program received signal SIGSEGV, Segmentation fault.
0x00000000004a4d90 in lol2 ()
(gdb) 

崩潰后堆棧似乎無法使用:

(gdb) bt
#0  0x00000000004a4d90 in lol2 ()
#1  0x000000000040669d in r2ad_info ()
#2  0x0000000000000000 in ?? ()

我究竟做錯了什么? 我該如何調試?

ccall只能導入函數,而lol2是沒有函數的。 使用帶有value限定的capi導入:

{-# LANGUAGE CApiFFI #-}
module Main where
-- ... etc ...
foreign import capi "test2.h value lol2" fun_ptr :: FunPtr Fun
-- ... etc ...

這不是很明顯,但手冊說要這樣做,並且它有效。 您看到的警告信息仍然出現; 我認為您可能想將其報告為錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM