C++で作成したDLLをPerlから呼び出し実行することができましたので、この流れについて記載します。
環境
OS Windows11 HOME
perl stawberry perl
perl 5.38 (ロケールでja_jp.utf-8をサポートしなくなったので、警告が出ていますが使えます)
ダウンロード先 Strawberry Perl for Windows
(Locale ‘Japanese_Japan.932’ is unsupported, and may crash the interpreter.)
準備
stawberry perl からCPANを使用してWin32::APIをインストールします
c:\ > cpan
:
Starting with version 2.29 of the cpan shell, a new download mechanism
is the default which exclusively uses cpan.org as the host to download
from. The configuration variable pushy_https can be used to (de)select
the new mechanism. Please read more about it and make your choice
between the old and the new mechanism by running
:
cpan[1]> install Win32::API
cpan[2]> force install Encode::compat
※stawberry perl bin内のgmakeを使ってインストールを行うので、stawberryperlが必須のようです
インストール中に
’gmake’ は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。
というエラーが出る場合は、gmakeが入っているフォルダにPATHを通したら治ります。
PATHの通し方
windowsボタンを右クリックして、システム設定を開く
設定の検索ボックスに、「環境」と入力
環境変数のPATHを編集し、「新規ボタン」からstawberryperlのPATHを登録
stawberryのインストール先\perl\bin
stawberryのインストール先\c\bin
を登録するのがポイントです
プログラムの作成
次のperlプログラムを作成しました
# load.pl
use strict;
use warnings;
use Win32::API;
my $dll_path = './Prime.dll'; # Prime.dllのパスを指定
my $function_name = 'isPrime'; # 関数名を指定
my $is_prime = Win32::API->new($dll_path, $function_name, 'I', 'I'); #I integer
die "Failed to load function: $^E" unless $is_prime;
my $number_to_check = 17;
my $result = $is_prime->Call($number_to_check);
if ($result) {
print "$number_to_check is prime.\n";
} else {
print "$number_to_check is not prime \n";
}
このperlファイルと同じフォルダにPrime.dllを配置します
実行結果
C:\??\dlltest>perl load.pl
Locale 'Japanese_Japan.932' is unsupported, and may crash the interpreter.
17 is a prime.
perlからC++で作成したDLLの関数を実行することができました。
つまづいた点(恥ずかしながら)
①Win32::API のインストール
gmake.exeにPATHが通っていないとインストールができず、gmake.exeを探すのに時間がかかってしまいました。
②DLLを呼び出す関数の仕様
WIN32APIを使ったDLLロードの部分で、
Win32::API->new($dll_path, $function_name, ‘int‘, ‘int‘); #誤った指令
と記述したために
Win32::API invalid return type, structs and callbacks as return types not supported at C:/?/?/perl/vendor/lib/Win32/API.pm line 376.
というエラーが出てしまい、原因特定に時間を要しました。
さらに、new($dll_path, $function_name, ‘I‘, ‘I‘);のIは、大文字でも小文字でも動きます。
最後に
C++で作成したDLLをperlから呼び出すことができました。
Prime.hファイルがなくても実行できることも初めて知りました。
自分でやってみないとわからないこと多いですね。