[英]Problems creating a unmanaged regular MFC DLL and call it from an managed C++ .NET app
我有一些关于DLL的问题。 我尝试了很多,但我无法得到完整的图片。 大多数例子都在C#等。
使用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 = "?SayHello@Cmfc_mainApp@@QAEHH@Z",
ExactSpelling = true)]
static int SayHello(int a);
......
private: System::Void button_Click(System::Object^ sender, System::EventArgs^ e)
{
int retval = SayHello(2);
}
我的问题是:
1 - 为什么在SayHello函数中没有init = 12并且应用程序崩溃(错误:尝试读取或写入受保护的内存)时它是否正常工作?
2 - 在这种情况下执行InitInstance()虽然我没有调用它(为什么没有ExitInstance)?
3 - 为什么我在使用DLLImport时看到一些给出EntryPoint的例子,有些则没有?
4 - 我可以将委托作为参数提供给MFC C ++ DLL中的函数而不是普通函数指针,以创建回调吗?
方法不能被P / Invoked。 如果要从非托管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); }
在C#中准备P / Invoked外部方法(你已经知道如何去做了,所以我省略了这些)
创建类的实例:
IntPtr instance = MyClass_Create();
然后调用它的方法:
int i = MyClass_MyMethod(instance, 4, 2.0);
最后,破坏班级:
MyClass_Destroy(instance);
不要忘记添加一些错误检查 - 我省略它以保持示例清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.