【发布时间】:2011-03-02 01:46:44
【问题描述】:
我正在尝试从我的 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++ 应用程序似乎可以在任何地方运行。
有什么想法吗?
谢谢,贡萨洛
【问题讨论】:
-
我推荐使用
IntPtr而不是int(对于所有指针,这包括来自LoadLibrary的返回类型) -
感谢您的建议,但很遗憾这不起作用。
-
究竟是哪个函数导致了崩溃?全部?
-
@Sam Skuce 不知道你的意思,我只是在 c++ 程序集中调用一个函数。