2012-09-20 62 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( ); 現在工作正常:) –

相關問題