2

DLL を動的にロードし、そのメソッドを呼び出す必要があります

C コード ヘッダー:

__declspec(dllexport) int Init_Normalization_EN(char* path);
__declspec(dllexport) const char* Process_Normalization_EN(char* input);

[extern] を使用してライブラリとメソッドを静的に定義する C# コード:

[DllImport("TextNormalization_EN.dll", EntryPoint = "?Init_Normalization_EN@@YAHPAD@Z", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern int Init_Normalization_EN(IntPtr path);

[DllImport("TextNormalization_EN.dll", EntryPoint = "?Process_Normalization_EN@@YAPBDPAD@Z", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern IntPtr Process_Normalization_EN(IntPtr input);

これらの宣言を使用すると、(init と正規化のプロセスの両方で) 相互運用性は正常に機能しますが、動的に DLL を指す必要があるため、次のコードを使用します。

クラスレベルで:

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private delegate int CallInit(IntPtr ipFolder);
private CallInit Init = null;

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private delegate IntPtr CallNormalize(IntPtr ipInput);
private CallNormalize Normalize = null;

コンストラクターで:

IntPtr pDll = NativeMethods.LoadLibrary(libraryPath);
IntPtr pAddressOfInit = NativeMethods.GetProcAddress(pDll, InitName);
Init = (CallInit)Marshal.GetDelegateForFunctionPointer(pAddressOfInit, typeof(CallInit));

IntPtr pAddressOfNormalize = NativeMethods.GetProcAddress(pDll, NormalizeName);
Normalize = (CallNormalize)Marshal.GetDelegateForFunctionPointer(pDll, typeof(CallNormalize));

IntPtr pFolder = Marshal.StringToCoTaskMemAnsi(dataFolderPath);
int result = this.Init(pFolder);
if (result != 0)
{
    InitializeCompleted = true;
}

このコードはすべて正常に実行され、フォルダーパスを使用してノーマライザーを初期化する呼び出しも正常に機能します (0 以外のハンドルを返します) が、テキストノーマライザーを実行しようとすると:

IntPtr pInput = Marshal.StringToCoTaskMemAnsi(text);
IntPtr pResult = this.Normalize(pInput);

2 行目に、アプリケーション レベルの例外 (try/catch ではキャッチできない) が表示されます。

[extern] 宣言のように IntPtr として取得しようとする返された文字列が原因であることが理解できる限りです。

4

1 に答える 1

3

この行はすべきではありません:

Normalize = (CallNormalize)Marshal.GetDelegateForFunctionPointer(
    pDll,
    typeof(CallNormalize));

なれ

Normalize = (CallNormalize)Marshal.GetDelegateForFunctionPointer(
    pAddressOfNormalize,
    typeof(CallNormalize));
于 2013-08-13T11:53:01.097 に答える