C#使用LoadLibrary / GetProcAddress时调用C函数崩溃

时间:2013-08-13 11:46:40

标签: c# .net dll interop marshalling

我需要动态加载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);

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

所有这些代码运行正常甚至调用init文件夹路径的规范化工具正常工作(返回句柄非零) 但 当我尝试运行text-normalizer时:

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

我在第二行遇到了应用程序级异常(try / catch无法捕获): “试图读取或写入受保护的内存。这通常表明其他内存已损坏。”

据我所知,返回的字符串是我尝试获取的IntPtr,如[extern]声明中那样

1 个答案:

答案 0 :(得分:3)

不应该这一行:

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

Normalize = (CallNormalize)Marshal.GetDelegateForFunctionPointer(
    pAddressOfNormalize,
    typeof(CallNormalize));
相关问题