hishidaの開発blog

EBシリーズ(EBPocket,EBWin,EBMac,EBStudio),KWIC Finder,xdoc2txt,読書尚友の開発者ブログ

xdoc2txt Dll版の使用方法について

xdoc2txtはVer2.0以降 Dll版も提供しているが、DllImportでdllをロードした場合(例1)、アプリケーション終了までDllのメモリは解放されない。
通常は問題ないが、連続して大量のファイルのテキスト抽出を行うと、入力ファイルによってメモリーリークが生じたり、クラッシュしたりする場合があることがわかった。

xdoc2txt dll版を使用して連続的にファイル抽出を行うアプリケーションを作成される場合、(例2)のように、ファイル抽出毎に毎回 LoadLibrary,FreeLibraryでdll のロード・解放を行っていただく方法を推奨したい。(実験したが、性能低下もそれほどはない)

(例1) DllImportによる方法

[DllImport("xd2txlib.dll", CharSet=CharSet.Unicode)]
public static extern int ExtractText(
[MarshalAs(UnmanagedType.BStr)] String lpFileName,
bool bProp,
[MarshalAs(UnmanagedType.BStr)] ref String lpFileText);


string fileName = "sample.doc";
string fileText = "";
int fileLength = ExtractText( fileName, false, ref fileText );

(例2) LoadLibrary、FreeLibraryによる動的ロード・解放(推奨)

// LoadLibrary、FreeLibrary、GetProcAddressをインポート
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32", SetLastError = true)]
internal static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);


// 関数をdelegateで宣言する
public delegate int ExtractText(
[MarshalAs(UnmanagedType.BStr)] String lpFileName,
bool bProp,
[MarshalAs(UnmanagedType.BStr)] ref String lpFileText);


string fileName = "sample.doc";
string fileText = "";
// 動的にdllをロードし、使用後に解放
IntPtr handle = LoadLibrary("xd2txlib.dll");
IntPtr funcPtr = GetProcAddress(handle, "ExtractText");


ExtractText extractText = (ExtractText)Marshal.GetDelegateForFunctionPointer(funcPtr, typeof(ExtractText));
int fileLength = extractText(fileName, false, ref fileText);
FreeLibrary(handle);


なお、xdoc2txt2.02の配布パッケージに、C#VB.Netそれぞれの動的ロードのサンプルプログラムを追加した.
http://www31.ocn.ne.jp/~h_ishida/xdoc2txt.html