C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了编译用haskell和模板haskell编写的共享对象,并将其与c中的main链接大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试将几个有文化的 haskell(.lhs)文件编译为共享对象(.so),然后将其与用c编写的主文件链接.但是,这里的问题是,用于创建.so文件中有2个是模板haskell.我遵循了使用模板haskell编译.so的规则,这意味着我执行了以下步骤:
我静态地编译了每个.lhs文件
然后我动态第二次编译它们.
3.我从步骤1和步骤1中获得的目标文件中创建了共享对象. 2.
我将main.c编译成main.o
我从第3步和第3步创建了一个可执行文件. 4.

有3个文件,从中创建.so. Dep1.lhs,Dep2.lhs& Dep3.lhs,用c写的主要内容

当我编译makefile时,我收到此消息:

并且创建了一个可执行文件’main’,但是当我尝试运行它时,会发生以下情况:

我试图在最后一个规则(主要)中包含’-l’选项中’libHSbase-4.6.0.1-ghc7.6.3.so’的目录,以便它将加载它.但它似乎不起作用.可能有人对错误有所了解吗?

Dep1.lhs的代码

> {-# LANGUAGE TemplateHaskell #-} <br/>
> {-# LANGUAGE ForeignFunctionInterface #-} <br/>

> module Dep1 where

> import Foreign <br/>
> import Foreign.C.Types <br/>
> import Dep3 <br/>

> data MyData = MyData
>    { foo :: String
>,bar :: Int
>    }

> emptyShow ''MyData

> foreign export ccall some_func :: IO () <br/>
> foreign export ccall factorial :: Int -> Int

> some_func :: IO () <br/>
> some_func = print $MyData { foo = "bar",bar = 5 }

> factorial :: Int -> Int <br/>
> factorial 0 = 1  <br/>
> factorial n = n *(factorial $n - 1)

Dep3.lhs的代码(来这里是因为Dep1.lhs导入它):

> {-# LANGUAGE TemplateHaskell,FlexibleInstances #-}

> module Dep3 where

> import Language.Haskell.TH

> emptyShow :: Name -> Q [Dec] <br/>
> emptyShow name = [d|instance Show $(conT Name) where show _ = "some meaningful sentence"|]

Dep2.lhs的代码

> {-# LANGUAGE ForeignFunctionInterface #-}

> module Dep2 where <br/>

> import Foreign    <br/>
> import Foreign.C.Types

> foreign export ccall power :: CInt -> CInt

> power :: CInt -> CInt
> power n = n*n
@H_347_10@main.c的代码

#include <stdlib.h>
#include <stdio.h>
#include <String.h>
#include <HsFFI.h>

#ifdef __GLASGOW_HASKELL__
#include "Tal2_stub.h"
#endif

#ifdef __GLASGOW_HASKELL__
extern void __stginit_power ( void );
#endif

// int power(int i){ return i*i; }

int fact(int i){
  if (i == 0) return 1;
  else return i * fact(i-1);
}
nt main(int argc,char *argv[]){
  hs_init(&argc,&argv);

#ifdef __GLASGOW_HASKELL__
  hs_add_root(__stginit_power);
#endif

 printf("what is 5!?\n");
 char buf[2048];
 scanf("%s",buf);
 int x = atoi(buf);
 if(x == fact(5)){
   printf("You're right!\n");
 } else {
   printf("You're wrong!\n");
 }
 printf("what is the power of 2?\n");
 scanf("%s",buf);
 x = atoi(buf);
 if(x == power(2)){
   printf("You're right!\n");
 } else {
   printf("You're wrong!\n");
 }
 hs_exit();
 return 0;
}

我的makefile代码

all : clean main

main : shared main.o
        gcc -o main main.o -L/usr/local/lib/ghc-7.6.3 -L/usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0/ -l. -lShared -Wl,/usr/local/lib/ghc-7.6.3 -L/home/tal/a_prerequisites/new_haskell/ghc-7.6.3/libraries/base/dist-install/build/libHSbase-4.6.0.1-ghc7.6.3. -lHstemplate-haskell-2.8.0.0 

main.o : 
    gcc -O2 -I/usr/local/lib/ghc-7.6.3/include -L/usr/local/lib/ghc-7.6.3 -L/usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0/ -c Main.c -o main.o 

shared : dep3second dep2second dep1second
        ghc -O2 -dynamic -shared -fPIC Dep1.dyn_o Dep2.dyn_o Dep3.dyn_o -o    libShared.so -lHSrts-ghc7.6.3

dep1second : dep1first
    ghc -c Dep1.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main -XForeignFunctionInterface -o Dep1.dyn_o -osuf dyn_o -hisuf dyn_hi   

dep2second : dep2first
    ghc -c Dep2.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main -XForeignFunctionInterface -o Dep2.dyn_o -osuf dyn_o -hisuf dyn_hi

dep3second: dep3first
    ghc -c Dep3.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main    -XForeignFunctionInterface -o Dep3.dyn_o -osuf dyn_o -hisuf dyn_hi

dep1first :
    ghc -c Dep1.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep1.o  

dep2first :
    ghc -c Dep2.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep2.o

dep3first :
    ghc -c Dep3.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep3.o

.PHONY : clean
clean :
    -rm -f *.o *.hi *.so *.dyn_hi *.dyn_o main

解决方法

注意:我对Haskell的了解有限,而且这个答案根本没有假设Haskell.

错误说:

这意味着在尝试执行程序时,找不到共享对象.请注意链接期间和执行期间查找共享对象之间的区别.

粗略地说,当您使用-L和-l链接到共享对象时,链接未完全完成,但记得在运行时完成.当您执行依赖于该共享对象的可执行文件时,其他人(不是编译器)必须能够找到共享对象并进行链接:再次粗略地说,Linux.

所以你需要让Linux找到你的共享对象.有几种方法可以这样做,其中一些方法已被弃用.我建议的方法是使用共享对象的路径编写一个文件,并将其放在/etc/ld.so.conf.d/下.然后,以root身份执行ldconfig(例如使用sudo),Linux应该能够找到共享对象.

我没有对此进行测试,但是如果您只是编辑/etc/ld.so.conf并添加一行包含.,那么Linux应该能够找到共享对象,如果该共享对象位于执行可执行文件的同一目录中.这可以用于开发,但如果要安装共享对象,我不建议使用它.

大佬总结

以上是大佬教程为你收集整理的编译用haskell和模板haskell编写的共享对象,并将其与c中的main链接全部内容,希望文章能够帮你解决编译用haskell和模板haskell编写的共享对象,并将其与c中的main链接所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。