系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
System.AccessViolationException when handing an array over to a dynamically loaded c++ DLL in C#
我正在一个C#程序中动态加载一个最初用C++编写的DLL,并将一个数组作为参数移交,如下所示:
// That's only for being able to load the DLL dynamically during runtime
[DllImport(@"C:WindowsSystem32kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string dllToLoad);
[DllImport(@"C:WindowsSystem32kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport(@"C:WindowsSystem32kernel32.dll", EntryPoint = "FreeLibrary")]
public static extern bool FreeLibrary(IntPtr hModule);
// Delegate with function signature for the DISCON function
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U4)]
delegate void DisconDelegate(float[] arr);
static void Main(string[] args){
// Load DLL
IntPtr _dllhandle = IntPtr.Zero;
DisconDelegate _discon = null;
string dllPath = @"D:myProjectTrivial_discon.dll";
_dllhandle = LoadLibrary(dllPath);
var discon_handle = GetProcAddress(_dllhandle, "DISCON");
_discon = (DisconDelegate)Marshal.GetDelegateForFunctionPointer(discon_handle, typeof(DisconDelegate));
// create the array and change it after its initialization
float[] arr = new float[] { 5, 6, 7 };
arr[0] = 7;
_discon(arr);
}
请注意,初始化后我再次使用arr[0] = 7;
作为数组的一个条目进行更改。这将返回以下错误:系统。AccessViolationExceptionHResult=0x80004003消息=试图读取或写入受保护的内存。这通常表示其他内存已损坏。来源=StackTrace:
但是,如果我不使用arr[0] = 7;
,它会起作用。
所以我想知道:为什么在这种情况下初始化后更改数组的条目会有问题?我该如何解决这个问题,即如何在初始化后更改数组的条目,并且仍然能够将其作为参数移交给DLL?
您需要将数组从托管内存转换为非托管内存。尝试以下
static void Main(string[] args)
{
Data data = new Data();
data.arr = new float[] { 5, 6, 7 };
IntPtr arrPtr = Marshal.AllocHGlobal(data.arr.Length * sizeof(float));
Marshal.StructureToPtr(data, arrPtr, true);
}
[StructLayout(LayoutKind.Sequential)]
public struct Data
{
public float[] arr;
}
相关文章:
- 从 wxWidgets 中的.DLL加载图标
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 无法使用c++/cli包装从c#dll加载函数
- 混合延迟 dll 加载和手动调用 LoadLibraryA 是否安全?
- 无法从 dll 加载函数
- 如何设置我的dll加载,该dll取决于Env-ailiable的某些第三部分DLL
- 将本机非托管的C DLL加载到托管的C#应用中,导致DLL输出垃圾
- 无法在 Python 3.5 上导入 cv2 DLL 加载失败
- 当使用“空dllmain”的dll加载链接到DLL时,应用程序无法启动(0xc0000142)
- 如何从DLL加载的DLL链接到函数
- 如何从Java中的C DLL加载和使用结构和功能
- 我可以用具有相同功能名称的多个DLL加载元素吗?
- 窗口挂钩和 dll 加载
- CEGUI-从DLL加载资源
- 什么可能导致时间函数和 DLL 加载之间死锁
- 以下代码是如何工作的(从DLL加载动态类)
- 错误:Visual Studio中没有为opencv_world310.dll加载符号
- 使用 LoadLibraryA 的 dll 加载错误
- 从 WinAPI C 项目中的专用 DLL 加载图像资源
- 模块"MyShellExt.dll"加载失败