2012-12-01 50 views
3

我對DLL的幾個問題調用它。我嘗試了很多,但我無法得到完整的圖片。大多數的例子是在C#等問題創建一個非託管常規MFC DLL和從託管C++ .NET應用程序

隨着VS2005嚮導我創建了一個非託管的MFC規則DLL(必須是因爲剩下的代碼MFC)。然後我嘗試將它導入到VS2005託管的.NET C++應用程序中。見下面的代碼。

mfc_main.h:

//--------------------------------------------------------- 
// mfc_main.h : main header file for the mfc_main DLL 
//--------------------------------------------------------- 

#pragma once 

#ifndef __AFXWIN_H__ 
    #error "include 'stdafx.h' before including this file for PCH" 
#endif 

#include "resource.h"  // main symbols 

class __declspec(dllexport) Cmfc_mainApp : public CWinApp 
{ 
public: 
    Cmfc_mainApp(); 

// Overrides 
public: 
    virtual BOOL InitInstance(); 

    int SayHello(int j); 

    int init; 
    DECLARE_MESSAGE_MAP() 
}; 

mfc_main.cpp:

//---------------------------------------------------------------- 
// mfc_main.cpp : Defines the initialization routines for the DLL. 
//---------------------------------------------------------------- 

#include "stdafx.h" 
#include "mfc_main.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 

BEGIN_MESSAGE_MAP(Cmfc_mainApp, CWinApp) 
END_MESSAGE_MAP() 

Cmfc_mainApp::Cmfc_mainApp() 
{ 
} 

Cmfc_mainApp theApp; 

BOOL Cmfc_mainApp::InitInstance() 
{ 
    CWinApp::InitInstance(); 

    return TRUE; 
} 

int Cmfc_mainApp::SayHello(int j) 
{ 
    init = 12; // Comment this out the application works !!!! 

    return j * 6; 
}; 

應用

[DllImport("mfc_main.dll", 
     EntryPoint = "[email protected][email protected]@[email protected]", 
     ExactSpelling = true)] 
static int SayHello(int a); 

...... 

private: System::Void button_Click(System::Object^ sender, System::EventArgs^ e) 
    { 
     int retval = SayHello(2); 
    } 

我的問題是:

1 - 爲什麼它不工作init = 12 e函數SayHello和應用程序崩潰(錯誤:試圖讀取或寫入受保護的內存)?

2 - 在這種情況下的InitInstance()執行的,雖然我不把它(以及爲什麼沒有ExitInstance中)?

3 - 爲什麼我看到一些例子使用的DllImport和一些不給予時的入口點?

4 - 我可以給一個委託作爲參數傳遞給函數在MFC C++ DLL,而不是一個正常的函數指針,以創建一個回調?

+1

你不能捏住C++實例方法,它們必須是靜態的。 –

回答

0

方法不能被P /調用。如果你想從非託管DLL中導出一個類用於託管世界,那麼你必須將它扁平化,例如。

  • 創建一個構造函數,它看起來像:

    __declspec(dllexport) void * __stdcall MyClass_Create() 
    { 
        return new MyClass(); 
    } 
    
  • 創建一個析構函數,它看起來像:

    __declspec(dllexport) void * __stdcall MyClass_Destroy(MyClass * instance) 
    { 
        delete instance; 
    } 
    
  • 拼合方法調用。讓我們假設,你必須在你的類下面的方法:

    int MyClass::MyMethod(int i, double j) { ... } 
    

    然後,你必須創建以下功能:

    __declspec(dllexport) int __stdcall MyClass_MyMethod(MyClass * instance, int i, double j) 
    { 
        return instance->MyMethod(i, j); 
    } 
    
  • 準備P/C#中調用外部方法(你已經知道如何做到這一點,所以我會忽略這些)

  • 創建類的實例:

    IntPtr instance = MyClass_Create(); 
    

    然後調用它的方法:

    int i = MyClass_MyMethod(instance, 4, 2.0); 
    

    最後,消滅階級:

    MyClass_Destroy(instance); 
    

不要忘記添加一些錯誤檢查 - 我忽略它使例子清晰。

相關問題