创建非托管常规 MFC DLL 并从托管 C++ .NET 应用程序调用它时出现问题

2024-04-10

我有几个关于 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);
    

不要忘记添加一些错误检查 - 我省略了它以保持示例清晰。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建非托管常规 MFC DLL 并从托管 C++ .NET 应用程序调用它时出现问题 的相关文章

随机推荐

  • Oracle 动态旋转

    我有下表 我需要根据 CCL 列创建列 CCL 列中的值未知 我不知道从哪里开始 任何帮助 将不胜感激 TABLEA ID CCL Flag 1 john x 1 adam x 1 terry 1 rob x 2 john x Query
  • Blackberry Java 中的类之间调用

    当屏幕上 单击 位图时 我试图推送一个新屏幕 为此 我从这篇文章中创建了一个类 黑莓可点击位图字段 https stackoverflow com questions 5722875 blackberry clickable bitmapf
  • 安装 gem 时出错:无法为 cygwin 的堆保留空间,Win32 错误 487

    我正在尝试安装win32 api我的机器上安装了 gem 并且在构建本机扩展时遇到了一些问题 gem install win32 api no ri rdoc Temporarily enhancing PATH to include De
  • 如何为WinForm、C#制作框架?

    我一直在研究改变Windows窗体边框的颜色 发现它是由Windows决定的 好吧 这是有道理的 所以我看到以前问过这个问题的人被告知去这里http customerborderform codeplex com http customer
  • 内存警告后 WKWebView 变为空白

    我正在开发一个 iOS 应用程序 它将在 wkWebView 中显示一些 360 度全景内容 该页面确实会加载 但当它收到内存警告时 它会在 iPad 2 上显示空白视图 相关代码 NSURLRequest req NSURLRequest
  • @selector 和其他类 (Objective-C)

    在对象内部我使用 NSMenu 的addItemWithTitle action keyEquivalent 创建 NSMenuItems 问题是我希望调用另一个对象上的方法作为操作 这action 部分需要一个 selector作为参数
  • pinterest 布局样式的 CSS 代码

    我的挑战是尝试使列表网格视图看起来像 pinterest 类似的布局 我已经用它编写了一些代码 但这还不够 下面的行彼此不匹配 content category grid view li featured position relative
  • Expressjs Passport-Local 无法注销

    我将应用程序 Passport local 复制粘贴到我的应用程序上 有趣的是我可以登录用户 但我不能让他们注销 app get logout function req res req logout res redirect 这并不是什么都
  • SQL Server Express 中的链接服务器

    我正在开发一个应用程序 其中我在 SQL Server Express 中有一个本地数据库 在本地数据库中工作期间 我们需要在另一个 SQL Server 实时服务器上执行查询 并返回一个值 并使用该值在本地服务器中执行查询 对 2 或 3
  • Angular 6:无法绑定到“formGroup”,因为它不是“form”的已知属性?

    我曾在 Angular 2 4 中使用过表单生成器 但现在我在 Angular 6 中使用它 我看到了这个问题 无法绑定到 formGroup 因为它不是 form 的已知属性 https stackoverflow com questio
  • 如何使用 ts 中的变量作为 HTML 文件中的标记名? [复制]

    这个问题在这里已经有答案了 我想知道是否有什么方法可以使用HTML tag name p for e g 这是从变量获得的 以下是我尝试过的代码 应用程序组件 ts import Component OnInit from angular
  • 在 Jupyter Notebook 中的 %matplotlib inline 之后使用 %matplotlib Notebook 不起作用

    我正在使用 Jupyter Notebook 来绘制饼图 In 第一个细胞用我的代码我有一个神奇的命令 matplotlib inline在这个神奇的命令之后 我运行我的代码 一切正常并且我的图形呈现 But in 第二个细胞当我设置 ma
  • Tensorboard 错误:当前数据集没有活动的仪表板

    我正在尝试使用 Tensorboard 但每次使用 Tensorflow 运行任何程序时 当我转到 localhost 6006 查看可视化时都会收到错误 这是我的代码 a tf add 1 2 b tf multiply a 3 with
  • getResponseHeader 不是函数

    我需要从另一个页面获取值 但我通过以下代码收到此错误 我该如何修复它 document ready function name submit click function ajax type POST data form signup se
  • 如何为异步流服务器编写 pytest 夹具?

    我一直在尝试学习 asyncio 但找不到任何创建可用于测试服务器代码的 pytest 夹具的示例 一旦服务器启动 我猜它会阻止其他一切 因此测试永远不会运行 pytest asyncio 是否有办法在单独的线程中运行固定装置或其他东西 还
  • Swift - 调用中的额外参数

    我试图从 DetailViewController 类调用 ViewController 类中声明的函数 尝试调试 调用中的额外参数 错误时会弹出 在 ViewController 类中 func setCity item Cities i
  • 如何创建匹配键的查询?

    我使用另一个用户 赞助商 的密钥来指示谁是用户的赞助商 它会在数据存储中为那些拥有赞助商的用户创建一个链接 最多可以是一个 但赞助商可以赞助许多用户 例如在本例中 ID 2002 赞助了另外三个用户 在这种情况下 这个查询做了我想要的 SE
  • 结合 Spark Streaming + MLlib

    我尝试使用随机森林模型来预测示例流 但似乎我无法使用该模型对示例进行分类 这是pyspark中使用的代码 sc SparkContext appName App model RandomForest trainClassifier trai
  • 应用内消息传递不会在自定义事件上显示消息

    using implementation com google firebase firebase analytics 17 2 1 implementation com google firebase firebase inappmess
  • 创建非托管常规 MFC DLL 并从托管 C++ .NET 应用程序调用它时出现问题

    我有几个关于 DLL 的问题 我尝试了很多 但无法获得完整的图片 大多数示例都是用 C 等编写的 使用 VS2005 中的向导 我创建了一个非托管 MFC 常规 DLL 由于剩余代码 必须是 MFC 然后我尝试将其导入 VS2005 管理的