-->

未处理的异常:System.AccessViolationException:尝试读取或写入(Unh

2019-09-22 16:32发布

下面是我的C ++ DLL

// DLL.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
//#include <stdexcept> 
#include<iostream>
using namespace std; 

typedef void (*FunctionPtr)(int); 
void (*FunctionPtr1)(int); 
extern "C" __declspec(dllexport)void Caller();
extern "C" __declspec(dllexport)void RegisterFunction(FunctionPtr func_ptr); 


    extern void Caller() 
    {    

        int i = 10;
        FunctionPtr1(i);
 } 

    extern void RegisterFunction(FunctionPtr func_ptr1)
 {
     FunctionPtr1 = func_ptr1;

 }

该DLL将得到refernce从C#函数名和参数传递给C#的功能。这里是我的C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;



namespace test
{
    class Program
    {

        [DllImport("C:/Users/10602857/Documents/Visual Studio 2010/Projects/DLL/Debug/DLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void Caller();

       [DllImport("C:/Users/10602857/Documents/Visual Studio 2010/Projects/DLL/Debug/DLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern fPointer  RegisterFunction(fPointer aa);

        static void Main(string[] args)
            {
                    Console.WriteLine("DLL Linking");
                    fPointer abc = new fPointer(ping);
                    RegisterFunction(abc);      //send address of function to DLL
                    Caller();                   //call from DLL
            }

        public  delegate void fPointer(int s);       // point to every functions that it has void as return value and with no input parameter 


        public static void ping(int a)
             {
                     Console.WriteLine("ping executed " + a);
             }

        public static void add1()
              {
                      Console.WriteLine("add executed");
              }

    }
}

C#代码是能得到我如下paseed在C ++ DLL的值

int i = 10;
        FunctionPtr1(i);

m如果您的sedired输出,但progrram得到了在最后坠毁与以下execption

Unhandled Exception: System.AccessViolationException: Attempted to read or write
 protected memory. This is often an indication that other memory is corrupt.
   at test.Program.Caller()

为什么我收到这个?

Answer 1:

好吧,我写测试代码为您服务。 概念很简单。

  1. 您可以使用C ++或C写的DLL

  2. CLR库(托管的DLL)包装您的DLL。

  3. C#代码可以通过CLR库使用原生的DLL。

原生的DLL

MyDll.cpp

#include "stdafx.h"

#include<iostream>
using namespace std; 

typedef void (*FunctionPtr)(int); 
void (*FunctionPtr1)(int); 
extern "C" __declspec(dllexport)void Caller();
extern "C" __declspec(dllexport)void RegisterFunction(FunctionPtr func_ptr); 


extern void Caller() 
{    
    int i = 10;
    FunctionPtr1(i);
} 

extern void RegisterFunction(FunctionPtr func_ptr1)
{
    FunctionPtr1 = func_ptr1;
}

您的CLR库,包装为本地DLL

MyDllCLR.h

#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;

typedef void (*FunctionPtr2)(int); 
extern "C" __declspec(dllimport)void Caller();
extern "C" __declspec(dllimport)void RegisterFunction(FunctionPtr2 func_ptr); 

namespace MyDllCLR {

    void MyFunc(int i);

    public ref class Class
    {        
    public:
        delegate void FunctionDelegate(int i);
        static FunctionDelegate^ fun;

        static void Caller1()
        {
            Caller();
        }

        static void RegisterFunction1(FunctionDelegate^ f)
        {
            fun = f; // Wrapper MyFunc call this delegate

            // this occurs runtime error and I don't know why.
            // So I wrote Warpper MyFunc() method. I usually do like this.
            //IntPtr p = Marshal::GetFunctionPointerForDelegate(fun);
            //RegisterFunction((FunctionPtr2)(void*)p);

            // Register Function Wrapper instead of user delegate.
            RegisterFunction(MyFunc);
        }
    };    
}

MyDllCLR.cpp

#include "stdafx.h"
#include "MyDllCLR.h"

void MyDllCLR::MyFunc(int i)
{
    MyDllCLR::Class::fun(i);
}

使用本机DLL C#代码

Program.cs中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestMyDllCLR
{
    class Program
    {
        static void MyFunc(int i)
        {
            Console.WriteLine("Come on! {0}", i);
        }

        static void Main(string[] args)
        {
            MyDllCLR.Class.RegisterFunction1(MyFunc);
            MyDllCLR.Class.Caller1();
        }
    }
}

您需要既为Program.cs的机DLL和CLR DLL

而且,当然,这不是你的目标的唯一途径。 :)



Answer 2:

它很可能是因为您的委托

fPointer abc = new fPointer(ping);

越来越了所使用之前收集的垃圾。 你需要存储的类的字段的参考代表,以确保其存活类的寿命。

尝试定义fPointer abcmain然后分配new fPointer(ping)到这里面main ,看看有没有什么帮助。



Answer 3:

所有我需要做的是..只是我的申报委托作为...

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
public delegate void MyDelegate(); 


文章来源: Unhandled Exception: System.AccessViolationException: Attempted to read or write