.NET通过P/Invoke调用C API触发System.AccessViolationException问题
P/Invoke调用C API触发System.AccessViolationException异常
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
调用一个void类型的C API时触发上述异常,该API的输入是仅包含基础类型的结构体。目前已有多个使用更复杂结构体的API方法可正常运行,且异常在Debug和Release模式下均会出现。
当前发现特殊现象:在C/C++和C#两端的结构体中同时取消注释int placeholder字段后,代码即可正常运行,且P/Invoke传递的数据完全正确。另外在另一个包含int类型枚举和int字段的结构体中也遇到相同情况,必须添加第三个int成员才能避免触发异常。
环境配置
- VS 17 2022
- C++ 20
- .NET Framework 4.7.2
C/C++端代码
typedef struct { float visibility; //[m] Visibility range float thickness; //[m] Thickness of the fog layer // int placeholder; } Fog; /// @brief set fog data to be forwarded to the IG /// @param fog \ref Fuze::Interfaces::Fog with fog data /// @param regionId the id of the region to be updated extern "C" __declspec(dllexport) void SetFogData(const Fog* fog, int regionId); ///interface.cpp #include "Interface.h" #include <iostream> void SetFogData(const Fog* fog, int regionId) { std::cout << "\n\nForwarding fog data to plugins\n"; std::cout << "Fog data: " << fog->thickness << " " << fog->visibility << std::endl; }
C#端代码
using System.Runtime.InteropServices; namespace Fuze { [StructLayout(LayoutKind.Sequential)] public struct Fog { public float Visibility; // [m] Visibility range public float Thickness; // [m] Thickness of the fog // int placeholder; } static public class API { private const string dllPath = "Fuze_API.dll"; [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] public static extern void SetFogData(Fog fog, int regionId); } } // main.cs using static Fuze.API; class FakeClientDotNet { static void Main(string[] args) { Fuze.Fog fog = new Fuze.Fog(); fog.Thickness = 50.0f; fog.Visibility = 250.0f; SetFogData(fog, 0); System.Console.WriteLine("\nCompleted\n"); } }
内容的提问来源于stack exchange,提问作者user19905921
相关产品推荐
相关产品推荐

