【Perl】自作したDLLを呼び出す

Perl

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ファイルがなくても実行できることも初めて知りました。
自分でやってみないとわからないこと多いですね。