简体   繁体   English

C ++库问题

[英]C++ library issue

I'm trying to make a call to a C++ library from my C# code. 我正在尝试从我的C#代码中调用C ++库。 I also have a sample application written in C++ that invokes the same library, and works fine. 我也有一个用C ++编写的示例应用程序,该应用程序调用相同的库,并且运行良好。 However, the call from C# throws an error: 但是,来自C#的调用将引发错误:

Attempted to read or write protected memory. 尝试读取或写入受保护的内存。 This is often an indication that other memory is corrupt. 这通常表明其他内存已损坏。

The c# code is: 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;
}

This exact same code works on some computers, and it throws the error on others. 此完全相同的代码在某些计算机上有效,而在其他计算机上则引发错误。 However, the sample C++ app seems to work everywhere. 但是,示例C ++应用程序似乎可以在任何地方使用。

Any ideas? 有任何想法吗?

Thanks, Gonzalo 谢谢,贡萨洛

I'm guessing the crashing is occurring on computers running 64-bit OSs. 我猜想崩溃发生在运行64位操作系统的计算机上。 I don't know about your DoBondProbeOperation logic, but your PInvoke methods should be defined as follows: 我不知道您的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);

Where you compare hModule to 0 , instead compare to IntPtr.Zero 您将hModule0进行比较,而不是与IntPtr.Zero进行比较

EDIT: Fixed CharSet value for LoadLibrary 编辑: LoadLibrary固定CharSet

EDIT2: Also try changing your bondProbeCalc definition to the following: EDIT2:还可以尝试将bondProbeCalc定义更改为以下内容:

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

Or: 要么:

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

Comments on Marshal.GetDelegateForFunctionPointer indicate that calling conventions other than Stdcall are not supported, ie that specifying [UnmanagedFunctionPointer(CallingConvention.Cdecl)] on your delegate type is not effective. Marshal.GetDelegateForFunctionPointer注释指示不支持Stdcall之外的调用约定,即,在您的委托类型上指定[UnmanagedFunctionPointer(CallingConvention.Cdecl)]无效。 If this is indeed the case, you'll need to switch to using PInvoke to call bpStringCalc , recompile the native library to export the function with the __stdcall modifier, or write a shim in C++/CLI (as IJW interop would not have this calling convention restriction). 如果确实如此,则需要切换到使用PInvoke来调用bpStringCalc ,重新编译本机库以使用__stdcall修饰符导出函数,或在C ++ / CLI中编写垫片(因为IJW interop不会进行此调用)约定限制)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM