2012-09-20 65 views
1

下面是我的C++ DLL未处理的异常:System.AccessViolationException:尝试读取或写入

// 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#代码是能得到我在C++ DLL paseed如下值

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

+0

什么包裹C++使用C++/CLI的dll?根据我的经验,这很容易! –

+0

我是新来这..我可以实现它吗? –

回答

0

所有我需要做的是.. 刚刚宣布我的委托作为...

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

它很可能是因为您的委托

fPointer abc = new fPointer(ping); 

了所使用之前,它是越来越垃圾收集。 您需要将对委托的引用作为类的字段存储,以确保它在类的整个生命周期内都能存活。

尝试在main之外定义fPointer abc,然后在main之内指定new fPointer(ping)并查看是否有帮助。

+0

它不工作:( –

+0

@Nanhyrin - 其他想法? –

+0

嗯,你确定调用约定是正确的吗?你尝试过stdcall而不是cdecl吗?虽然我认为C++代码中的C表示cdecl,所以它是刺需要复制到FunctionPtr1,这相当于更改类型吗? – Nanhydrin

1

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

  1. 您使用C++或C

  2. CLR库(托管的DLL)包你的DLL写的DLL。

  3. 您的C#代码可以通过CLR库使用您的Native 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

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

同时需要对计划机DLL和CLR DLL C#代码。cs

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

+0

- 你的概念很好... 但我试图宣布我的代表为 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void MyDelegate( ); 现在工作正常:) –

相关问题