2012-12-02 115 views
2

基本上,我的代码在NucleoProf_init中崩溃,通过gdb的堆栈跟踪来判断,并且这是我调用的唯一函数。这个类型转换是否正确?

#include <HsFFI.h> 

static char *argv[] = {"NucleoProf", "", "", 0}; 
static int argc = 1; 

HsBool NucleoProf_init(void){ 

    // Initialize Haskell runtime 
    hs_init(&argc, (char***)&argv); 

    return HS_BOOL_TRUE; 
} 

我怀疑这是我通过argv的说法,或许,ARGV的类型转换的方式,因为堆栈跟踪包含以下内容:

#3 0x00007ffff5956282 in setFullProgArgv() 
    from /usr/lib/ghc/libHSrts-ghc7.4.1.so 
#4 0x00007ffff5956d04 in hs_init_ghc() from /usr/lib/ghc/libHSrts-ghc7.4.1.so 
#5 0x00007ffff5b9ed4f in NucleoProf_init() 

问:难道这就是正确的“合成”一个简单的命令行的方式?

回答

4

你可以试试这个:

char ** p = argv; 
hs_init(&argc, &p); 

目前还不清楚为什么需要按地址传递数组,但我不知道你正在使用的API。仔细检查手册,看看这些值是否可以通过该功能进行更改,以及之后是否需要对其进行处理。

+0

谢谢!您的解决方案有效(尽快接受)。我不知道为什么有人会以这种方式通过... – dsign

+0

@dsign:正如我所说,阅读文档。可能会修改'argc'的值(例如,打折“消耗的”参数),'argv'的情况可能类似。 –

+0

下面是我可以找到的所有文档:http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/ffi-ghc.html,在这个意义上它没有多少说明。显然,我错过了一些东西或者文档是错误的,因为该类型不能编译。但我同意他们很可能会尝试从argv中删除一些特殊选项。 – dsign

2

这是错误的,因为首先,它是错误的类型。取一个数组的地址会产生一个指向数组的指针。 &argv具有类型char *(*)[4],即“指向4个指向char的指针的数组的指针”。这不是您想要的char ***类型。您正在强制转换它以隐藏类型不兼容性。

你想要一个char ***,这是一个指向实际char **变量的指针。但是,您在任何地方都没有char **变量。你有argvchar *[4]变量,这是完全不同的。数组变量就是这样 - 它在内存中按顺序排列的元素的集合;没有任何地址存储在内存中的任何地方。

您的根本困惑可能是阵列不是指针。数组具有不同的大小(数组的大小是其长度乘以其组件类型的大小),指针和数组类型(指向数组的指针与指向指针的指针非常不同;与数组和指针数组相同)和语义(数组不能分配或传递)。在某些情况下,数组表达式可能会隐式地将降级为指针右值;但在这种情况下,您正在接收需要左值的地址,因此不适用。切勿将数组与指针混淆。