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);

当使用这些声明时,互操作工作正常(对于初始化和规范化过程),但我需要动态指向一个 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;
}

所有这些代码都运行正常,甚至使用文件夹路径调用规范化器也可以正常工作(返回非零句柄)但是当我尝试运行文本规范化器时:

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

我在第二行得到一个应用程序级异常(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 回答