• ベストアンサー

perlでWin32::APIを使用してDLLからバイナリデータを得たいのですが、

perlでWin32::APIを使用してDLLからバイナリデータを得たいのですが、 データ途中できれてしまいます。 0x00を含むところで切れているように思えます。 $datの長さを指定する方法とかあるのでしょうか? どうか助言をお願いします。 $func=new Win32::API("sample.dll","func1",[P,N,P],P); $size=0; $dat = $func ->Call("TEST",100,\$size); open(F,">kekka"); binmode(F); print F "$dat"; close(F);

  • cdar
  • お礼率55% (11/20)
  • Perl
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

Win32::APIを使ってバイト配列のようなデータを取得する場合、 関数の戻り値として得るのではなく 引数に書き込む場所を与えておいて、そこに書き込むという形が ほとんどだと思うのですが、 なぜ質問の例にあるような手順を取っているのでしょうか? Win32::APIの本体を見ると、場所をかんちがいしていなければ case T_POINTER: ApiFunctionPointer = (ApiPointer *) ApiFunction; #ifdef WIN32_API_DEBUG printf("(XS)Win32::API::Call: Calling ApiFunctionPointer()\n"); #endif pReturn = ApiFunctionPointer(); #ifdef WIN32_API_DEBUG printf("(XS)Win32::API::Call: ApiFunctionPointer returned 0x%x '%s'\n", pReturn, pReturn); #endif /* #### only works with strings... #### */ cReturn = (char *) safemalloc(strlen(pReturn)); strcpy(cReturn, pReturn); ということをやっているので、 \x00 というデータがあったらそこで切れるのは 当然のように思います。 #Perlでの文字列自体は 、長さを別に管理しているので #データとして\x00を含めることはできます。

cdar
質問者

お礼

補足とお礼がごっちゃになってしまいました。 戻り値の型Pの場合、文字列として新たに領域を確保して、返すことがわかり、大変参考になりました。 なんとか対処できました。ありがとうございます。

cdar
質問者

補足

利用したかったDLLがC言語用で、戻り値をポインターで返すようになっていたからです。 たしかに、検索しても領域を確保したものを引数に渡す例ばかりでてきました。 戻り値の型Pの場合、文字列として新たに領域を確保して、返すことがわかり、大変参考になりました。 戻り値を数値にして、そこからデータ変換をして取得する方法でなんとか対処できました。ありがとうございます。

その他の回答 (1)

noname#39970
noname#39970
回答No.1

"$"だからじゃない? http://www.tohoho-web.com/wwwperl1.htm 「バイナリ読み込み」参照

cdar
質問者

補足

回答ありがとうございます。もう少し、perlを勉強します。

関連するQ&A

  • 画像をバイナリデータに変換する方法

    ディレクトリ内にある『.gif』の画像~枚を 100kb単位でバイナリデータに変換して 『.dat』という拡張子で出力させたいと思っています。 Perlをふれた事はあまり無く、何から手を付ければ良いのかいまいちつかめません。 『.gif』を100kb単位でバイナリデータに変換する方法など、知っている方いましたら御教授お願い致します。 宜しくお願いします。

    • ベストアンサー
    • Perl
  • perlで配列のポインタをdllに渡すには?

    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を使うと、正常動作するようです。

    • ベストアンサー
    • Perl
  • Win32APIで作成したDLLをC#.NETで使用した時のDLL内の関数の動作について

    いつもお世話になっております。 今回ご教授頂きたい内容なのですが、 Win32APIで作成したDLLをC#.NETで使用した時のDLL内の関数の動作についておききします。 下記サイトで公開されている「ビットマップ形状に合わせてリージョンを作成する」CreateRgnFromBitmap関数についてなのですが、 http://orangeknowledge.jpn.org/tips/sdk001.html Win32APIでこの関数をDLL化したものをWin32APIで暗黙的リンク、明示的リンクで利用した場合は正常にCreateRgnFromBitmap関数が正常に動作するのですが、C#.NETで同DLLを利用した時に、関数を呼ぶ事はできますがなぜか正常に動作しません。 デバッグモードで処理内容をみてみたのですが、 // 一行分画像データを DIB で取り出す(bmpなので下から取り出す) GetDIBits(hDC, hBitmap, bm.bmHeight - y, 1, pScanData, (LPBITMAPINFO)&bi, DIB_RGB_COLORS); の部分でpScanData配列に一行分の画像データが正常に入っていませんでした。 そのためGetDIBitsの次に行う判定 // 一行分の透明/非透明の変化点を調査する for (int x = 0; x < bm.bmWidth; x++){ if (pScanData[x] != dwTransColor){ // 透明色でなければ ・・・省略・・・ で正常に判定が行われず引数としてわたされている「DWORD dwTransColor」透明色部分を正常に判定できていませんでした。 なぜWin32APIでは正常に動作するのにC#.NETでは正常に動作しないのでしょうか? 色々と試してみたのですがいっこうに分かりません。 ご教授よろしくお願い致します。

  • MySQLにバイナリデータを正常に保存できない

    ローカルに保存してあるファイルをMySQLにバイナリデータとして格納して保存したいと思ってます。 データは格納できるのですが、文字エンコード?の問題でファイルが壊れてしまっているみたいです。 格納後、出力した際にjpgなどの画像は問題なく表示されるのですが、xlsやpdfなどのファイルが開けなくなります。MySQLの文字コードはUTF8です。 #!/usr/bin/perl use DBI; my $dbh = DBI->connect('DBI:mysql:database:localhost:3306', 'user', 'password'); # ファイルパス my $file = '/tmp/test.xls'; # ファイルサイズ my $size = -s $file; # バイナリデータ読み込み my $line; open(IN, $file); binmode(IN); sysread(IN, $line, $size); close(IN); # DBに格納 my $sth = $dbh->prepare(qq|INSERT INTO file_table ( `file_name`, `file_data` ) VALUES (?, ?)|); $sth->execute('test.xls', $line); $dbh->disconnect; 上記のようなコードなのですが、おかしな点があれば教えてください。 よろしくおねがいします。

    • ベストアンサー
    • Perl
  • バイナリファイル(画像等)データをオフセットして読み込みたい

    タイトル見ただけではなんのこっちゃかもわかりませんが 行いたい事は以下の通りです。 バイナリファイル(画像ファイル)、仮に15Kバイトのサイズだったとします。 それを10Kバイト区切りで読み込みたい。 そして変数$str1,$str2に格納したい。 open(BIN, "< test.gif"); binmode(BIN); #ファイルの先頭から10Kバイト読み込んで変数$str1に代入 sysread(BIN, $str1, 10000); #上記で読み込んだ個所から、残りのデータを読み込みたい #オフセット10Kバイトから5Kバイト読み込む sysread(BIN, $str2, 5000,10000); close(BIN); のような処理でいいのかと思っていたのですが、 $str2には期待通りの形で格納されませんでした。 先頭の10000バイト(オフセットで指定したサイズ)がNULLになっており、 その先から残りのバイナリデータが格納されていました。 自分が行いたいのは、 $str2の先頭から、バイナリファイルのオフセットの値 (ここでは10Kの部分からのこりの5K) を格納したいのです。 この関数ではダメだと思うのですが、 自分の行いたい処理の関数が見当たらず困っております。 どなたかご存知の方、どうぞよろしくお願い致します。

    • ベストアンサー
    • Perl
  • perlで辞書データを置換

    perl超初心者です。 初めて組んで行き詰りました。 辞書データから不必要なものを取ろうと 思いましたが、いきなり[ファイルを開く] で止まってます。 以下がそうです。 use utf8; binmode STDIN, ":encoding(cp932)"; binmode STDOUT, ":encoding(cp932)"; open(DIC, "+<", "pdic2csv.csv") or die("Error:$!"); @array = <DIC>; $a = ~ s|" / "|"_"|g; @array = ("\,","\\","\s",1,2,3); $a = ~ s/1,2,3/"_"/g; $a = ~ s|" /// "|"\,"|g; close(DIC) ----------------- 使う辞書データは以下です。 うつる /// 건너다 / [綴り]ㄱㅓㄴㄴㅓㄷㅏ うつわ /// 그릇 / 그릇は,(~)杯, \ cf. 잔 うで /// 팔 よろしくお願いします。

  • バイナリファイルの出力

    「test.dat」というファイルをブラウザから ダウロードさせるためにバイナリ出力をしたいのですが、 空ファイルばかりできて上手くいきません。 以下のようなコードなのですが、どこが悪いでしょうか? ご教授ください。お願いします。 症状:ブラウザからダウンロードすると、ファイル名は正しいが 空のファイルになっている 環境:perl 5.8.7 windows server2003 ----------------------------------------------------------- #!/usr/local/bin/perl print "Content-Disposition: attachment; filename=\"test.dat\"\n"; print "Content-Type: application/octet-stream\n\n"; open(IN, "test.dat"); binmode(IN); binmode(STDOUT); print while (<IN>); close(IN); -----------------------------------------------------------

    • ベストアンサー
    • Perl
  • VS2010 バイナリデータ 初心者

    VBで処理を作成していたのですが、バイナリデータを編集する処理を追加する事になりました。 VC++なら、上手くデータをコンバート出来たのでVC++をDLL化して作成中です(もともとは6.0のVC++のプログラムです)。 新しくプロジェクト(VC++)を作成(WIN32プロジェクト)しVBから作成したDLLを呼び出す所までは上手く出来たのですが、肝心のバイナリデータをOPENする所が上手く行きません。 VC++の方でCFileを使用する際に#include <afx.h>でエラーになってしまいます。 先ほども投稿したのですが、結果惨敗だったので、再度質問するしだいですw バイナリのファイル:kalrt.bat #include <afx.h> wchar_t* pFileName; pFileName = L"kalrt.bat"; CFile fr;  ← エラー char buff[1000]; if (!fr.Open(pFileName, CFile::modeRead,NULL )){   while(fr.Read(buff,0x800)){ // ---処理--- } CFileを使用する場合は、MFCアプリケーションを使うとの内容を頂けたのですが、どのように構成したら良いか分かりません。いろいろとサイトを調べても見つけられませんでした。 分かりやすい説明があるサイトなどがありましたら、教えて下さい。 急いでいるので説明が上手く出来ていないので、説明が足りない場合は補足に記載します。 よろしくお願いします。

  • 文字列の抽出

    指定したファイルの中から'<'と'>'とで囲まれた部分文字列を抽出したいのですが方法がわかりません。どのようにしたらできるでしょうか? *ファイルは制御コードが混じっているのでバイナリとして扱わないといけないかもしれません。 よろしくお願い致します。 ------------------------------------------------- open(IN, "test.dat"); open(OUT, "> out.txt"); binmode(IN); while (<IN>) { /^<(\w+)>$/; print OUT "$1\n"; } close(IN); close(OUT);

    • ベストアンサー
    • Perl
  • 全行読み込むには

    open( IN, "pass.dat" ) or die "Can't open pass.dat: $!"; $f_data = <IN>; close( IN ) or die "Can't close pass.dat: $!"; $f_data1 = $f_data; $f_data2 = $f_data; $f_data1 =~ s/<br>//g; $f_data2 =~ s/\S//g; open( OUT, ">log.dat" ) or die "Can't open log.dat: $!"; select OUT; print "$f_data1"; print "$f_data2"; select STDOUT; close( OUT ) or die "Can't close word.js: $!"; 上記スクリプトでは、pass.datの一行目しか読み込まれません。全行を読み込むためにはどのように書き換えればいいのでしょうか?宜しくお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう