How to use C library from Haskell? - c

I am trying to call a C function from Haskell using the FFI and I keep getting this error :
ghc.exe: ^^ Could not load 'getSize', dependency unresolved. See top
entry above.
main: ByteCodeLink: can't find label During interactive linking, GHCi
couldn't find the following symbol: getSize This may be due to you
not asking GHCi to load extra object files, archives or DLLs needed by
your current session. Restart GHCi, specifying the missing library
using the -L/path/to/object/dir and -lmissinglibname flags, or simply
by naming the relevant files on the GHCi command line. Alternatively,
this link failure might indicate a bug in GHCi. If you suspect the
latter, please send a bug report to:
glasgow-haskell-bugs#haskell.org
I am using the stdio.h library in my C library:
C library
// lib.h
#include <stdio.h>
double getSize() {
double size = 0;
scanf("$f", &size);
return size;
}
FFI module
{-# LANGUAGE ForeignFunctionInterface #-}
module Ffi where
import Foreign
import Foreign.C.Types
foreign import ccall "lib.h getSize" c_size :: IO Double
Main
module Main where
import Ffi
main :: IO ()
main = do a <- getLine
b <- c_size
print $ "got from C: " ++ show b
Running script
gcc -o lib -lib.h
runghc main
P.S. Could this be because I somehow have to specify the dependency stdio.h somewhere else too?

Okay, there are several things to do here:
Rename "lib.h" to "lib.c". It's a C source file (containing code), not a C header file.
Ideally, add a separate "lib.h" header file with the prototype for getSize.
Fix the bug in "lib.c". You want "%lf" in place of "$f" to read in a double.
Compile the program with ghc instead of running it with runghc. A single ghc command can compile and link both Haskell modules and C code.
In other words, your files should look like:
// lib.c
#include "lib.h"
#include <stdio.h>
double getSize() {
double size = 0;
scanf("%lf", &size);
return size;
}
// lib.h
double getSize(void);
-- Ffi.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Ffi where
import Foreign
import Foreign.C.Types
foreign import ccall "lib.h getSize" c_size :: IO Double
-- Main.hs
module Main where
import Ffi
main :: IO ()
main = do a <- getLine
b <- c_size
print $ "got from C: " ++ show b
and you should compile it with:
$ ghc Main.hs lib.c
[1 of 2] Compiling Ffi ( Ffi.hs, Ffi.o )
[2 of 2] Compiling Main ( Main.hs, Main.o )
Linking Main ...
Then you can run it, supply a line for the Haskell getLine and a second line for the C scanf, and it should work fine:
$ ./Main
hello world!! -- line for Haskell
135.0 -- line for C
"got from C: 135.0"

Related

useDynLib() error and compileAttributes returns nothing: embedding a C library into an R package

I have a C package which builds a executable with several argument flags. One compiles the code with a Makefile (I know, this needs to change for the R package) and an executable is created to be run via
$ ./codeName -f path/inputfile -o path/outputfile -p ## -s "type"
My goal is to integrate several of the functions used in this C package to be used with an R library. I take a look at some examples on github.com/cran of R packages using C. In Writing R Extensions, it explains how I could use .Call() and Makevars to call the C functions from R. I would like to avoid that like the plague. However, it looks like this would require significant re-writing with SEXP object--so I turn to Rcpp (yeah!)
I create the package Rcpp.package.skeleton("packageName")
Great. Within R, I do the following:
$ R
> library(devtools)
> build() # works!
> install() # works!
> library(packageName)
> rcpp_hello_world()
## expected output
Everything works. Then I add my C package into /src. I then execute Rcpp::compileAttributes() in the package root directory via R--nothing happens and nothing is output, which is expected, as I haven't changed the C code at all yet.
I try installing with the commands above: devtools::build() and devtools::install(). Via the Makefile, it looks like the C code compiles perfectly! But then there's this issue:
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in library.dynam(lib, package, package.lib) :
shared object ‘packageName.so’ not found
Error: loading failed
Execution halted'
ERROR: loading failed
Well, that's somewhat confusing, and I don't know why that has occurred, but the snag is the useDynLib("packageName") in the NAMESPACE. If I remove this, the C code appears to compile and the package installs via the build/install commands above. rcpp_hello_world() still works.
(1) Why does this error ‘packageName.so’ not found appear now, and can I get around it?
(This question has nothing to do with Rcpp.)
Then, I go to a .c file. I add
#include <Rcpp.h>
using namespace Rcpp;
to a *.c file and //[[Rcpp::export]] before a function I would like to import. (I'm not sure that's going to work in *.c, or in a C header file.)
Next, I go to the package root directory, open R and try this:
$ R
> library(Rcpp)
> compileAttributes()
That runs without error. However, no RcppExports.R and RcppExports.cpp were generated. Compiling the C code also results in the error that it cannot find #include <Rcpp.h>.
(2) Why would compileAttributes() not function in this environment? I must be incorrectly using Rcpp and //[[Rcpp::export]] in order to wrap these C functions into R-usable format.
What would you call this function? C code?
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
It passes as both C and C++ code. So let's call it C code.
You can clearly interface this from R via Rcpp with the following caller:
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
Stick them all together into a C++ file so that Rcpp can operate on them (see comments) and you are all set.
R> library(Rcpp)
R> sourceCpp("/tmp/ex.cpp")
R> callFib(10)
[1] 55
R>
The complete file is below.
#include <Rcpp.h>
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
/*** R
callFib(10)
*/

How is Foreign Function Interface (FFI) used with Stack?

I was following some FFI tutorials and examples (here and here), and I was wondering what should change when using stack?
In the examples, the source C file is compiled to an object file using gcc -c -o termops.o termops.c and included in the gcc compilation using ghc --make -main-is FfiEx -o ffi_ex FfiEx.hs termops.o. How can the equivalent be accomplished using stack?
Here is as minimal an FFI C project as I could imagine.
$ cd c-proj
c-proj$ ls
Main.hs c-proj.cabal c_file.c
The contents of these files:
c-proj.cabal: describes the
name: c-proj
version: 0.1.0.0
cabal-version: >= 1.22
build-type: Simple
executable main
main-is: Main.hs
build-depends: base >= 4.9
c-sources: c_file.c
Main.hs: the only Haskell source file
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
foreign import ccall "plus_ten" plusTen :: Int -> IO Int
main = do
n <- plusTen 2
print n
c_file.c: the C source file
#include<stdio.h>
int plus_ten(int n) {
printf("%d + 10\n", n);
return n + 10;
}
Then, if you want to use Stack, you can run stack init.
$ stack init
<< Shell output snipped >>
$ stack build
<< Shell output snipped >>
$ stack exec main
2 + 10
12

OCaml - Compile OCaml and C code that uses Ctypes

I'm trying to learn how to call routines in C directly from OCaml code, using the Ctypes library.
I have this basic example with two files: hello.ml and hello.c.
hello.ml looks like this:
open Ctypes
open Foreign
let hello =
foreign "hello" (float # -> returning void)
;;
let () =
hello 3.15
;;
hello.c looks like this:
#include <stdio.h>
void hello(double x)
{
if ( x > 0)
printf("hello!\n");
}
How do I compile these two files into one executable?
The process of manually compiling/linking code is scary to me and I don't understand it very well. I usually use a Makefile template to compile my code because that's really easy.
Here's an example that I use on OS X.
in simple.c
int adder(int a, int b)
{
return a + b;
}
and in simple.ml
open Ctypes
open Foreign
let adder_ = foreign
"adder" (int #-> int #-> returning int)
let () =
print_endline (string_of_int (adder_ 1 2))
Then I do
clang -shared simple.c -o simple.so
ocamlfind ocamlopt -package ctypes.foreign -cclib simple.so -linkpkg simple.ml -o Test
./Test
And that should print out 3 on the terminal.

SystemVerilog: How to connect C function using DPI call in VCS simulator?

I have the following files:
C file with functions:
// funcs.c
#include <stdio.h>
void something() {
printf("something\n");
sayHello();
}
System verilog file:
// hello_world.v
module kuku;
export "DPI-C" function sayHello;
import "DPI-C" function void something();
initial something();
function int sayHello ();
$display("hello world");
sayHello = 1;
endfunction
endmodule
How can I compile it and make this work so when I call something() from SV, it will call the C function, and when I call sayHello() from C, it will call the SV function?
Answering myself:
When SV code is compiled using VCS, it is first translated into C code.
When exporting a function out of SV, it generates a C header file vc_hdrs.h that should be included by the C file.
So a change I made in the C file is to add the line:
#include "vc_hdrs.h"
Then, I just added the C functions file to the VCS compilation command:
> vcs -sverilog hello_world.v funcs.c
It works!
The output I get is:
something
hello world
.
A solution that works with all simulator that follow IEEE Std 1800-2012 is to have #include "svdpi.h" and prefix the extern keyword in front of all methods being exported to C. funcs.c should look like:
#include <stdio.h>
#include "svdpi.h"
extern int sayHello();
void something() {
printf("something\n");
sayHello();
}
Examples from IEEE Std 1800-2012
§ H.10.2 Example 2—Simple packed array application
§ H.10.3 Example 3—Application with complex mix of types
I see you've named SystemVerilog file as .v extension. Not sure if that works or not. But lets say if its hello_world.sv
Your command line should look like this (for Questa Simulator),
qverilog hello_world.sv funcs.c
"qverilog " is to compile and run SystemVerilog files.
That's all. No need to add extra header files
Hi I have provided a nice example under this post
https://stackoverflow.com/a/46441794/5842403
Synopsys VCS
1) You compile the C code using flags and introducing the defines you want to add.
In our case our C code need the define PYTHON_PATH
#GCC in two steps for shared object
gcc -g -D 'PYTHON_PATH="'$PYTHON_DIR'"' -fPIC -Wall -I${VCS_HOME}/include -I/usr/include/python2.6/ -lpython2.6 -c ${PROJECTDIR}/verification/PVE/keycontrol/tb/keycontrol_C_code_wrapper.c
gcc -fPIC -shared -o keycontrol_C_code_wrapper.so keycontrol_C_code_wrapper.o
2) You do the VCS elaboration linking the python lybrary with -LDFLAGS '-lpython2.6'
vcs -timescale=1ps/1ps -ntb_opts uvm -lca -kdb -full64 keycontrol_tb_top -debug_access+all+reverse -LDFLAGS '-lpython2.6'
3) You run the created simulation file. You call simv including -sv_lib keycontrol_C_code_wrapper to import the C shared object.
#RUN C CODE
./simv -gui -ucli +DVE +UVM_NO_RELNOTES -l simv.log +UVM_TESTNAME=keycontrol_basic_test -do ../../verification/PVE/keycontrol/tools/keycontrol_ucli_init.synopsys -sv_lib keycontrol_C_code_wrapper

How to pass a string from Haskell to C?

All I want to do is pass a plain-text string from Haskell to C. However, it says that [Char] is an unacceptable return type. I can't find anywhere why they think it is, nor what acceptable return types are.
I'm trying to make a very simple OS image that I can boot with Qemu.
Does anyone know how to do this? Thanks.
{-# 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
You want a CString.
Going from CString to String:
peekCString :: CString -> IO String
Going from String to CString:
withCString :: String -> (CString -> IO a) -> IO a
There's also Haddock documentation for module Foreign.C.String.
The general list of types that can be used in foreign declarations is specified as part of the Foreign Function Interface in the Haskell Report.
Edit
Ok, here's a very small example of a thing you can do, somewhat based on your sample code. Create a Haskell file CTest.hs with the following contents:
module CTest where
import Foreign.C
hello :: IO CString
hello = newCString "hello"
foreign export ccall hello :: IO CString
Then create a C file ctest.c with the following contents:
#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;
}
Then compile and run as follows:
$ ghc CTest
[1 of 1] Compiling CTest ( CTest.hs, CTest.o )
$ ghc -o ctest ctest.c CTest.o -no-hs-main
$ ./ctest
hello
I think what you need is System.IO.Unsafe.unsafePerformIO to convert IO CString to CString before sending the CString to C. newCString will convert a Haskell String to IO CString. Thus System.IO.Unsafe.unsafePerformIO $ newCString a can be passed to your C routine which will accept input of type char*. If your C routine returns static char* then System.IO.Unsafe.unsafePerformIO $ peekCString will give you back a Haskell string. You need to import System.IO.Unsafe. unsafePerformIO has an implementation in Foreign.C.String (or Foreign.C.Types ?) which is deprecated, so you have to use the full path. I had a hell of a time before I could find unsafePerformIO - probably because people are allergic to something that is so dangerous as to force declaration of impure to pure. newCString can lead to memory leaks if used repeatedly without cleaning. withCString may be a better option - will learn that later.

Resources