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