简体   繁体   English

当我从 C# 代码调用导入的 C++ 函数时,为什么会抛出 AccessViolationException?

[英]Why is an AccessViolationException thrown when I call an imported C++ function from C# code?

I have been reading many threads about the topic but I have not been able to find a solution to my problem yet.我一直在阅读有关该主题的许多主题,但我还没有找到解决我的问题的方法。

From my C# code, I try to call a C++ function by using DllImport .在我的 C# 代码中,我尝试使用DllImport调用 C++ 函数。 Unfortunately, I do not have the C++ code, but the header file gives information about the function:不幸的是,我没有 C++ 代码,但头文件提供了有关该函数的信息:

ABCD Initialize
(
  IN FLOAT a  
  , IN DWORD b  
);  

ABCD is defined in the header file as well: ABCD 也在头文件中定义:

#define EFGH extern "C"
...
#define ABCD EFGH __declspec(dllexport) HRESULT WINAPI

In C# code, I try to to call the Initialize function like this:在 C# 代码中,我尝试像这样调用 Initialize 函数:

[DllImport("path.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern UInt32 Initialize([In] float a, [In] UInt32 b);
...
Initialize(50.0f, 0);

According to this site there is no need for marshalling for the data type float , and instead of DWORD I can use UInt32 .根据这个站点,不需要对数据类型float进行编组,我可以使用UInt32而不是DWORD For the return type, HRESULT WINAPI , I use the data type UInt32 and in my understanding there no need for marshalling as well?对于返回类型HRESULT WINAPI ,我使用数据类型UInt32并且据我所知也不需要编组? (I also tried to use other data types for parameters and the return value, but always got the same exception) (我也尝试将其他数据类型用于参数和返回值,但总是遇到相同的异常)

For the DllImport attribute, many possibilities for CharSet and CallingConventions have been tested, but I had no success.对于 DllImport 属性,已经测试了CharSetCallingConventions许多可能性,但我没有成功。 When declaring the function, I also tried both variants, with and without the [In] attribute for the parameters.在声明函数时,我还尝试了两种变体,有和没有[In]属性的参数。

When the function is called, an exception is thrown:当函数被调用时,抛出异常:

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

Am I missing something here?我在这里错过了什么吗? What could be my next steps to call the function successfully?成功调用该函数的下一步是什么?

Thank you.谢谢你。


Here is the full C# code.这是完整的 C# 代码。 As said, I do not have the code that was used to build the .dll file.如前所述,我没有用于构建 .dll 文件的代码。 Also I am not allowed to share the dll.我也不允许共享 dll。

using System;
using System.Runtime.InteropServices;

namespace MyNamespace
{
  class Program
  {
    [DllImport("path.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
    public static extern UInt32 Initialize([In] float a, [In] UInt32 b);

    static void Main(string[] args)
    {
      Initialize(50.0f, 0); // <- throws System.AccessViolationException
      Console.ReadLine();
    }
  }
}

Finally, I could determine the problem.最后,我可以确定问题所在。

In order to check the data types of the parameters and the return value, I used the decompiler Snowman on the dll.为了检查参数的数据类型和返回值,我在dll上使用了反编译器Snowman It looked like the dll only defines interfaces, and that the implementations are in another dll file which the developer forgot to send in first place.看起来 dll 只定义了接口,并且实现在另一个 dll 文件中,开发人员首先忘记发送该文件。

Once the second .dll file is stored in the runtime folder of my program, the function call works.一旦第二个 .dll 文件存储在我程序的运行时文件夹中,函数调用就起作用了。 I also want to mention that the call works with and without [In] parameter attributes.我还想提一下,该调用可以使用和不使用[In]参数属性。

While I don't know the exact reason for the thrown exception AccessViolationException: Attempted to read or write protected memory... (I think another exception could fit better here), I am happy that the issue could be solved.虽然我不知道抛出异常的确切原因AccessViolationException: Attempted to read or write protected memory... (我认为另一个异常可能更适合这里),但我很高兴问题可以得到解决。

Thanks to Ben Voigt and David Heffernan for their comments!感谢Ben VoigtDavid Heffernan的评论!

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

相关问题 尝试调用导入的C ++函数时,C#:AccessViolationException - C#: AccessViolationException when trying to call an imported C++ function 当我调用从dll导入的方法时抛出AccessViolationException - AccessViolationException thrown when I call a method imported from dll Visual C#在包装的C ++ \\ CLI dll中调用Lapack时抛出System.AccessViolationException - System.AccessViolationException thrown by Visual C# on call to Lapack inside wrapped C++\CLI dll System.AccessViolationException从C#调用C ++函数 - System.AccessViolationException calling c++ function from C# 从C#到C ++非托管代码的多个函数调用导致AccessViolationException - Multiple function calls from C# to C++ unmanaged code causes AccessViolationException (C#)从C ++ DLL中获取char **时出现AccessViolationException - (C#) AccessViolationException when getting char ** from C++ DLL 从C#调用C ++时出现System.AccessViolationException - System.AccessViolationException when calling C++ from C# 创建C#到C ++的桥梁:为什么在调用DLL时会出现AccessViolationException? - Creating C# to C++ bridge: Why do I get a AccessViolationException when calling DLL? 从C#调用C ++ / CLI包装器时出现AccessViolationException - AccessViolationException when calling C++/CLI wrapper from C# 从C#上的dll调用C函数时出现AccessViolationException - AccessViolationException when calling C function from dll on C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM