Active Perlの最新版(x86)を使っています。
C言語側で、
//配列の先頭要素へのポインタと配列の要素数を渡すと、要素の平均を整数で返す関数
int avr(int *array,int kazu) {
int value=0;
for(int i=0;i<kazu;i++) {
value+=*(array+i);
}
return value/kazu;
}
などと書いて、avr.dllとしてビルドしたものを(モジュール定義はdefファイルにて指定)、
use Win32::API;
my $function = Win32::API->new("avr", "avr", "PN", "N");
@array=(1,2,3,4,5);
$avr=$function->Call(\@array,5);
print "Content-type: text/html\n\n";
print $avr;
と使ってみたのですが、出力値が期待の「3」ではなく、-123343252とか435893497などの無茶苦茶な数値になってしまいます。
配列のポインタの渡し方が違うのかとは思いますが、どう書いたら良いのか分からない状況です。
一応、他のプログラムからこのdllを使うと、正常動作するようです。
No.1ベストアンサー
- 回答日時:
Perl のリファレンスは C などのポインタじゃないよ.
Perl から C の関数を呼びたいなら... XS?
この回答への補足
ご返信ありがとうございます。
>Perl から C の関数を呼びたい
というより、dll化された関数を呼んで、その結果をperlの変数に収めたいです
XS等を使うとなると、同じコードを2箇所に書くことになりかねないので、避けたいです。
cの方でポインタを使わなければ、うまく呼べるのですが・・・
dllの関数を使う場合、配列のすべての要素を渡すしか方法は無いのでしょうか?
結局色々と調べて、どうやらperlでは実メモリのアドレスを得ることは不可能らしいという結論に辿り着きました。
幸い、渡そうとしている配列は一桁の整数の配列なので、C側で
//数字の文字列へのポインタを渡すと、各文字の平均を整数で返す関数
int avr(const char *array,int kazu) {
int value=0;
for(int i=0;i<kazu;i++) {
value+=array[i]-48; /* ASCII文字の数字から普通の数字へ変換 */
}
return value/kazu;
}
として、perlで
use Win32::API;
my $function = Win32::API->new("avr", "avr", "PN", "N");
@array=(1,2,3,4,5);
#配列から渡すべき文字列を作る
my $str="";
foreach (@array) {
chomp $_; #この場合は要らないが、ファイルから読み込んだ配列等の場合は必要
$str.=$_;
}
$avr=$function->Call($str,5); #avr('12345',5);
print "Content-type: text/html\n\n";
print $avr;
などとしてみたところ、正常に動きました。
根本的な解決ではないのですが、これで解決と致します。
Tacosanさんのおかげで、「perlでは実メモリのアドレスを得ることは不可能」ということに気がついたので、ベストアンサーに致します。
Tacosanさん、t-okuraさん、ありがとうございました。
No.2
- 回答日時:
Win32::API は使ったことないのですが、
http://search.cpan.org/~cosimo/Win32-API-0.64/AP …
をみると、 int の引数に対応するのは N ではなく、 I じゃないですか。
この回答への補足
ご回答ありがとうございます。
Iだと、int型
Nだと、long int型
になるようです。
Iで再度実行してみましたが、以前めちゃくちゃな値のままです。
もしかして、perl自体に、実際のメモリアドレスを得る手段は無いのでしょうか・・・?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
マクロ Publicでの配列定義
-
perlで配列の要素が空なのを知...
-
クラスに配列を渡す方法
-
perlで2次元配列をサブルーチ...
-
二次元配列における要素数のは...
-
delphi の 標準偏差のプログラ...
-
Strawberry Perl for Windows ...
-
perl 配列の要素数について
-
文字の整列(printf)
-
ファイルからデータを読み込ん...
-
Excel VBA ユーザーフォームの...
-
VBAのautofilter、criteriaの配...
-
エクセルVBAでTransposeの不思議
-
VBA 二次元配列 ループの書き方
-
jcode->jfold で禁則処理
-
DataGridViewに配列の値を表示...
-
バイナリデータの操作
-
二次元配列のインデックスについて
-
画面を強制的に再描画させる方法
-
Escキーを押すと、中断する時と...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのautofilter、criteriaの配...
-
Excel VBA ユーザーフォームの...
-
クラスに配列を渡す方法
-
Dim flag(4) as boolean で配列...
-
二次元配列における要素数のは...
-
マクロ Publicでの配列定義
-
二次元配列のインデックスについて
-
リストボックスに縦スクロール...
-
組み合わせについての質問です...
-
チェックボックスのperlでの値...
-
perlで配列の要素が空なのを知...
-
文字の整列(printf)
-
エクセルVBAでTransposeの不思議
-
VBScript 配列
-
一致する要素が格納されている...
-
fortran
-
VB6で配列の最大値を簡単に求め...
-
複数のキーで配列をソートする...
-
VBA 多次元配列を用いてグルー...
-
jcode->jfold で禁則処理
おすすめ情報