gpt4 book ai didi

从 C 调用 Haskell FFI 函数 Ptrs

转载 作者:太空狗 更新时间:2023-10-29 17:06:25 27 4
gpt4 key购买 nike

我正在尝试让下面的代码工作:

sample_hs :: CInt -> (CInt -> CInt)
sample_hs x = (x+)

foreign export ccall sample_hs :: CInt -> (CInt -> CInt)

我希望能够在 c: 中做这样的事情

pf = sample_hs(2);
result = pf(3); //Should be 5;

但是,当我尝试这样做时,我收到一条错误消息:

error: too few arguments to function ‘sample_hs’

我猜测语言之间的接口(interface)并没有像我想象的那样工作。有没有办法做我想做的事?

最佳答案

有可能,FFI 确实允许导出高阶函数。不过需要对您的 Haskell 进行一些修改:

{-# LANGUAGE ForeignFunctionInterface #-}
module Main where

import Foreign.C.Types
import Foreign

foreign export ccall sample_hs :: CInt -> IO (FunPtr Sample)

type Sample = CInt -> CInt
foreign import ccall "wrapper" mkSample :: Sample -> IO (FunPtr Sample)

sample_hs :: CInt -> IO (FunPtr Sample)
sample_hs x = mkSample (x+)

main = return ()

Haskell 中的高阶函数是通过使用明确的 FunPtr 类型导出的。为了清楚起见,我在本例中将更高阶的类型命名为 Sample。为了能够创建函数指针,您需要使用“包装器”函数,因此需要额外的 FFI 声明。

我还没有测试过这个,但它应该可以正常工作,无论如何它都能编译。更多关于 FunPtr here

-- EDIT 我已经测试过它并且工作正常。按预期返回 5。

如果您有机会在 Windows 上执行此操作,我有一个关于 hackage 的软件包 Hs2Lib这将导出 Haskell 函数并自动为您将它们编译为 .DLL。它还为您提供了 C/C++ 和 C# 的包含。但是,如果您使用的是 Linux,我仍在努力。

不要脸的外挂:P

使用 Hs2Lib,您的文件中唯一需要的是:

module Test where

-- @@ Export
sample_hs :: Int -> IO (Int -> Int)
sample_hs x = return (x+)

和对 Hs2lib 的简单调用

PS C:\Users\Phyx\Desktop> hs2lib .\Test.hs
Linking main.exe ...
Done.

IO 和显式返回的原因是 Int -> (Int -> Int) 只是 Int -> Int -> Int,因为类型是右结合的。但是 Int -> IO (Int -> Int) 表明你想要返回一个函数。它在 IO 中,因为创建函数指针是一种副作用操作。为了完整起见,使用的 C 文件是:

#include <stdio.h>
#include <stdlib.h>
#include "Hs2lib_FFI.h"

/*
*
*/
int main(int argc, char** argv) {

HsStart();

CBF1_t pf = sample_hs(2);
int result = pf(3);
printf("%d\n", result);

HsEnd();
return (EXIT_SUCCESS);
}

所以它非常即插即用。但同样,它目前仅适用于 Windows。

关于从 C 调用 Haskell FFI 函数 Ptrs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7909395/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com