Delphi から MeCab(libmecab.dll)を呼び出す
Delphi から libmecab.dll を呼び出すユニット
32bit, 64bit 共用です(生成exeとMeCabで合わせて下さい)
libmecab.dll と辞書ディレクトリのパスをコンストラクタで指定して下さい
呼出ユニット
unit MeCab;
interface
uses
Winapi.Windows, System.SysUtils, System.Classes;
type
PMecabTagger = Pointer;
PMecabNode = Pointer;
T_mecab_new = function(argc: Integer; argv: PPChar): PMecabTagger; cdecl;
T_mecab_destroy = procedure(tagger: PMecabTagger); cdecl;
T_mecab_sparse_tostr = function(tagger: PMecabTagger; str: PAnsiChar): PAnsiChar; cdecl;
TMeCab = class
private
FTagger: PMecabTagger;
F_mecab_new: T_mecab_new;
F_mecab_destroy: T_mecab_destroy;
F_mecab_sparse_tostr: T_mecab_sparse_tostr;
function LoadDllFunc(DllPath: string): Boolean;
public
constructor Create(DllPath: string; Args: array of string); overload;
constructor Create(DllPath, DicDir: string); overload;
destructor Destroy; override;
function Parse(const Text: string): string;
end;
implementation
function AllocPPChar(StrArray: array of string): PPChar;
begin
Result := AllocMem(SizeOf(PChar) * Length(StrArray));
{$POINTERMATH ON}
for var I := Low(StrArray) to High(StrArray) do begin
Result[I] := PChar(StrArray[I]);
end;
{$POINTERMATH OFF}
end;
constructor TMeCab.Create(DllPath: string; Args: array of string);
var
ArgArray: PPChar;
begin
if (not LoadDllFunc(DllPath)) then begin
raise Exception.Create('Failed to load DLL.');
end;
ArgArray := AllocPPChar(Args);
try
FTagger := F_mecab_new(Length(Args), ArgArray);
if (FTagger = nil) then begin
raise Exception.Create('Failed to initialize MeCab.');
end;
finally
FreeMem(ArgArray);
end;
end;
constructor TMeCab.Create(DllPath, DicDir: string);
begin
Create(DllPath, ['mecab', '-d', DicDir]);
end;
destructor TMeCab.Destroy;
begin
if Assigned(FTagger) then begin
F_mecab_destroy(FTagger);
end;
inherited;
end;
function TMeCab.LoadDllFunc(DllPath: string): Boolean;
var
LibHandle: THandle;
begin
LibHandle := LoadLibrary(PChar(DllPath));
if (LibHandle <> 0) then begin
@F_mecab_new := GetProcAddress(LibHandle, 'mecab_new');
@F_mecab_destroy := GetProcAddress(LibHandle, 'mecab_destroy');
@F_mecab_sparse_tostr := GetProcAddress(LibHandle, 'mecab_sparse_tostr');
Result := Assigned(F_mecab_new) and Assigned(F_mecab_destroy) and Assigned(F_mecab_sparse_tostr);
end else begin
Result := False;
end;
end;
function TMeCab.Parse(const Text: string): string;
var
ResultPtr: PAnsiChar;
AnsiText: UTF8String;
begin
if (not Assigned(FTagger)) then begin
Exit('');
end;
AnsiText := UTF8String(Text);
ResultPtr := F_mecab_sparse_tostr(FTagger, PAnsiChar(AnsiText));
Result := string(UTF8String(ResultPtr));
end;
end.
使い方
uses MeCab
:
var MeCab: TMeCab;
begin
MeCab := TMeCab.Create('C:\Program Files\MeCab\bin\libmecab.dll', 'C:\Program Files\MeCab\dic\ipadic');
try
dstStr = MeCab.Parse('和布蕪による日本語解析');
finally
MeCab.Free;
end;
end;
※MeCabの改行コードは #10 です
コメント