c# - 未处理的异常 : System. AccessViolationException:尝试读取或写入

标签 c# c++ dll dllimport dllexport

下面是我的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 将从 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# 代码能够获取我在 c++ dll 中 paseed 的值,如下所示

int i = 10;
        FunctionPtr1(i);

M 获得了 sedired 输出,但程序在执行后崩溃了

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()

为什么我会收到这个??

最佳答案

好的,我给你写了测试代码。 概念很简单。

  1. 您使用 C++ 或 C 编写了 dll。

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

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

您的 native 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 库, native 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);
}

使用 native 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 需要 Native DLL 和 CLR DLL

当然,这不是实现您目标的唯一方法。 :)

关于c# - 未处理的异常 : System. AccessViolationException:尝试读取或写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12509252/

相关文章:

c# - 我可以在后台线程中使用 Screen 类吗?

c# - 绑定(bind)源的意外行为

c# - 创建计时器并启动它并随时获取它的值 c#

c++ - std::string 构造函数如何处理固定大小的 char[]?

c++ - 为什么在 C++ 静态 DLL 链接中使用 LIB?

qt - qt5 简单应用程序无法在 Windows 7 中运行

c# - 构造/制作通用类型并将类型约束转换为结构作为基础类型的约束

java - 以编程方式定期更改桌面墙纸

c++ - 如何使用 log4cpp 一次记录多个变量?

c++ - 在控制台中创建dll的方法