[英]How to pass a string from Haskell to C?
我想要做的就是將一個純文本字符串從 Haskell 傳遞給 C。但是,它說 [Char] 是一種不可接受的返回類型。 我找不到他們認為的任何原因,也找不到可接受的返回類型。
我正在嘗試制作一個可以使用 Qemu 啟動的非常簡單的操作系統映像。
有誰知道如何做到這一點? 謝謝。
{-# LANGUAGE ForeignFunctionInterface #-}
module Hello where
import Foreign
import Foreign.C.String
import Foreign.C.Types
hello :: String -> (CString -> IO a) -> IO a
hello = "Hello, world!"
foreign export ccall hello :: String -> (CString -> IO a) -> IO a
你想要一個CString
。
從CString
到String
:
peekCString :: CString -> IO String
從String
到CString
:
withCString :: String -> (CString -> IO a) -> IO a
還有模塊Foreign.C.String
Haddock 文檔。
可以在foreign
聲明中使用的類型的一般列表在 Haskell 報告中指定為外部函數接口的一部分。
好的,這是您可以做的事情的一個很小的例子,有點基於您的示例代碼。 使用以下內容創建 Haskell 文件CTest.hs
:
module CTest where
import Foreign.C
hello :: IO CString
hello = newCString "hello"
foreign export ccall hello :: IO CString
然后創建一個包含以下內容的 C 文件ctest.c
:
#include <stdio.h>
#include "CTest_stub.h"
int main (int argc, char *argv[]) {
hs_init(&argc, &argv);
printf("%s\n", hello());
hs_exit();
return 0;
}
然后編譯運行如下:
$ ghc CTest
[1 of 1] Compiling CTest ( CTest.hs, CTest.o )
$ ghc -o ctest ctest.c CTest.o -no-hs-main
$ ./ctest
hello
我認為你需要的是System.IO.Unsafe.unsafePerformIO
在將 CString 發送到 C 之前將 IO CString 轉換為 CString。newCString 會將 Haskell 字符串轉換為 IO CString。 因此System.IO.Unsafe.unsafePerformIO $ newCString a
可以傳遞給您的 C 例程,該例程將接受char*
類型的輸入。 如果你的 C 例程返回 static char*
那么System.IO.Unsafe.unsafePerformIO $ peekCString
會給你一個 Haskell 字符串。 您需要導入System.IO.Unsafe
。 unsafePerformIO
在Foreign.C.String
(或Foreign.C.Types
?)中有一個已棄用的實現,因此您必須使用完整路徑。 在我找到unsafePerformIO
之前,我unsafePerformIO
很unsafePerformIO
——可能是因為人們對某些危險的東西過敏,以至於強制聲明不純為純。 newCString
如果不清理就重復使用會導致內存泄漏。 withCString
可能是更好的選擇 - 稍后會學習。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.