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

2 に答える 2

4

これを試すことができます:

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

配列をアドレスで渡す必要がある理由は不明ですが、使用している API はわかりません。これらの値を関数で変更できるかどうか、および後で処理する必要があるかどうかを確認するには、マニュアルを再確認してください。

于 2012-12-02T16:53:17.910 に答える
2

間違っているのは、まず、型が間違っているからです。配列のアドレスを取得すると、配列へのポインターになります。&argvtype char *(*)[4]、つまり「charへの4つのポインターの配列へのポインター」を持っています。これはchar ***あなたが望むタイプではありません。型の非互換性を隠すために強制的にキャストしています。

実際の変数char ***へのポインタである が必要です。しかし、どこにも変数char **がありません。char **あなたは完全に異なる変数を持っargvています。char *[4]配列変数はまさにそれです。つまり、メモリ内のシーケンス内の要素のコレクションです。メモリ内のどこにも保存されているもののアドレスはありません。

あなたの根本的な混乱は、配列がポインターではないという事実かもしれません。配列には、さまざまなサイズ (配列のサイズは、コンポーネント タイプのサイズを掛けた長さ)、ポインターおよび配列の型 (配列へのポインターは、ポインターへのポインターとは大きく異なります。配列の配列とポインターの配列と同じです) があります。 )、およびセマンティクス (配列を割り当てたり渡したりすることはできません)。状況によっては、配列式が暗黙的にポインターの右辺値に分解されることがあります。ただし、この場合、左辺値が必要なアドレスを取得しているため、適用されません。配列とポインターを混同しないでください。

于 2012-12-02T20:51:04.270 に答える