2017-08-29 7 views
1

私はPerlコードとCコードを持っています。私はPerlコードでC関数を呼び出しています。 私はPerlからCにfloat配列を渡して(これはhttp://www.perlmonks.org/?node_id=39697のように)、うまく動作します!Perl、C、XS - float配列をアンパック

私が試してみました
my $p_angle = pack("f*", @angle); 

しかし、今、私は私のC関数からのPerlにその配列を返すようにしようとしていますし、私はそれで何かを行うことができるようにしたい、などの値を読み、印刷...

my @array = unpack("f*", $entropy); 

しかし、それはまったく動作しません、私は@アレイを印刷するとき、私はいつも同じ妥当な値ではないと思っています。

私は間違っていると思いますが、誰かが正しく配列を解凍する方法を知っていますか?

+3

1)XSコードを見ることなく、何が間違っているかは実際にはわかりません。アンパックについては、それ自体が間違っていることは何もありません。 2)そのポストはかなり悪いアドバイスのIMOです。戻り値に対して直接それをフォローしようとしているのであれば、おそらくメモリ管理ミスをしているでしょう。スタック上で通常のやり方でやることをお勧めします。 – hobbs

+1

ポストは 'char *'を引数とするperlからのC関数を呼び出します。これは十分に機能します。 PerlがC出力にNULL( '\ 0')を見つけたときに読み込みを停止するので、CからPerlへの逆の' char * 'の引き渡しは手間がかかります。 – mob

+2

コードを表示していないため、間違ったことを伝えることはできません。問題の最小限かつ実行可能なデモンストレーションを提供してください。 – ikegami

答えて

3
use strict; 
use warnings; 
use feature qw(say); 

use Inline C => <<'__EOS__'; 

#include <stdio.h> 

SV* test(SV* sv) { 
    float* array; 
    size_t num_eles; 
    { 
     STRLEN len; 
     char* s = SvPVbyte(sv, len); 
     num_eles = len/sizeof(float); 

     /* We can't just cast s because we could */ 
     /* run afoul of alignment restrictions. */ 
     array = malloc(len); 
     memcpy(array, s, len); 
    } 

    { 
     size_t i; 
     for (i=0; i<num_eles; ++i) { 
     printf("%zu %.6f\n", i, (double)(array[i])); 
     } 
    } 

    { 
     SV* return_sv = newSVpv((char*)array, num_eles*sizeof(float)); 
     free(array); 
     return return_sv; /* The typemap will mortalize. */ 
    } 
} 

__EOS__ 

my @a = (1.2, 1.3, 1.4); 
say sprintf "%u %.6f", $_, $a[$_] for 0..$#a; 
my $a = pack('f*', @a); 
my $b = test($a); 
my @b = unpack('f*', $b); 
say sprintf "%u %.6f", $_, $b[$_] for 0..$#b; 
関連する問題