C ++库问题

时间:2011-03-02 01:46:44

标签: c# c++ c

我正在尝试从C#代码调用C ++库。我还有一个用C ++编写的示例应用程序,它调用相同的库,并且工作正常。但是,来自C#的调用会引发错误:

  

尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

c#代码是:

#region DllImports

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
static extern bool FreeLibrary(int hModule);

[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
delegate string bondProbeCalc(string licenseFolder, string requestString);

#endregion


/// <summary>
/// Calls Bondprobe to calculate a formula
/// </summary>
internal static string DoBondProbeOperation(string requestString)
{
    if (string.IsNullOrEmpty(requestString)) throw new ArgumentNullException();

    //Reference library
    int hModule = LoadLibrary(ConfigurationManager.Instance.BondProbeSettings.AssemblyFilePath);

    if (hModule != 0)
    {
        IntPtr intPtr = GetProcAddress(hModule, "bpStringCalc");

        bondProbeCalc funcDelegate = (bondProbeCalc)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(bondProbeCalc));

        requestString = requestString.EndsWith("=") ? requestString.Substring(0, requestString.Length - 1) : requestString;

        string returnValue = funcDelegate(ConfigurationManager.Instance.BondProbeSettings.LicenseFilePath, requestString);

        FreeLibrary(hModule);

        return returnValue;
    }

    return string.Empty;
}

这个完全相同的代码适用于某些计算机,并且会将错误抛给其他计算机。但是,示例C ++应用程序似乎无处不在。

有什么想法吗?

谢谢Gonzalo

2 个答案:

答案 0 :(得分:0)

我猜测在运行64位操作系统的计算机上发生了崩溃。我不知道你的DoBondProbeOperation逻辑,但你的PInvoke方法应定义如下:

[DllImport("kernel32.dll", CharSet = CharSet.Auto]
static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32.dll"]
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

[DllImport("kernel32.dll"]
static extern bool FreeLibrary(IntPtr hModule);

hModule0进行比较,而不是与IntPtr.Zero进行比较

编辑:修复CharSet

LoadLibrary

EDIT2:还可以尝试将bondProbeCalc定义更改为以下内容:

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
delegate string bondProbeCalc(string licenseFolder, string requestString);

或者:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate [MarshalAs(UnmanagedType.LPStr)] string bondProbeCalc([MarshalAs(UnmanagedType.LPStr)] string licenseFolder, [MarshalAs(UnmanagedType.LPStr)] string requestString);

答案 1 :(得分:0)

Comments on Marshal.GetDelegateForFunctionPointer表示不支持除Stdcall之外的调用约定,即在您的委托类型上指定[UnmanagedFunctionPointer(CallingConvention.Cdecl)]无效。如果确实如此,则需要切换到使用PInvoke调用bpStringCalc,重新编译本机库以使用__stdcall修饰符导出函数,或者在C ++ / CLI中编写填充程序(因为IJW互操作不会有这个调用约定限制。)