簡體   English   中英

如何將字符串從 Haskell 傳遞給 C?

[英]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

CStringString

peekCString :: CString -> IO String

StringCString

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 unsafePerformIOForeign.C.String (或Foreign.C.Types ?)中有一個已棄用的實現,因此您必須使用完整路徑。 在我找到unsafePerformIO之前,我unsafePerformIOunsafePerformIO ——可能是因為人們對某些危險的東西過敏,以至於強制聲明不純為純。 newCString如果不清理就重復使用會導致內存泄漏。 withCString可能是更好的選擇 - 稍后會學習。

暫無
暫無

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

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