• [.NET]非托管代码调用托管代码


    最近在做一个项目的时候遇到这样一个问题,需要为设备商提供的程序提供一些可调用的函数用于扩展其功能,供应商的程序使用早期的delphi 6编写,最好的办法就是把这些功能函数封装为普通的windows DLL,但是这些功能和另外一个已经完成的项目可以重用,唯一的问题就是那个项目是用C#编写的,从非托管代码是不能直接使用这些托管对象类型的。我们知道托管DLL文件的PE格式除了普通PE文件的格式外,更多的是IL代码和元数据,IL代码是要在CLR中由JIT编译成本CPU的指令集的指令来运行的,所以是不能直接象使用普通windows DLL那样装载使用托管dll的。

    一种办法是把托管类包装为COM对象,在MSDN有介绍如何来操作:http://msdn.microsoft.com/en-us/library/aa645712%28VS.71%29.aspx,这种办法颇为麻烦,个人也不太喜欢COM的操作方式,那么还有其他的办法吗?这就是使用托管VC++做一个中间过渡的DLL。下面以一个普通windows控制台程序调用显示.net的一个form为例来简单看看是如何实现的。

    首先创建一个C#的Class library工程clrform,往工程中添加一个form:

    namespace clrform
    {
        public partial class MyForm : Form
        {
            public MyForm()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Message from .net form.");
                this.DialogResult = DialogResult.OK;
            }
    
            public int ShowMe()
            {
                if (this.ShowDialog() == DialogResult.OK)
                    return 1;
                return 0;
            }
        }
    }

    再创建一个visual c++的clr class library项目clrdll来包装.net form,visual studio会自动添加clr支持,在reference中添加前面的模块clrform,主要的代码类似:

    extern "C"  __declspec(dllexport) int __stdcall ShowMyForm()
    {
        clrform::MyForm^ myform=gcnew clrform::MyForm();
        return myform->ShowMe();
    
    }

    最后来创建一个win32的控制台程序来调用clrdll的ShowMyForm:

    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
        int nRetCode = 0;
    
        // initialize MFC and print and error on failure
        if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
        {
            _tprintf(_T("Fatal Error: MFC initialization failed\n"));
            nRetCode = 1;
        }
        else
        {
            int i=ShowMyForm();
            std::cout<<i;
            getchar();
        }
    
        return nRetCode;
    }

    整个过程就是这样的简单了,这里没有参数的传递,在实际的例子中还需要注意参数的类型转换,比如从.net的string到mfc的CString等等。

    另外.net SDK也提供CLRCreateInstance(在MSCorEE dll中实现)来创建和宿主自己的CLR,在这个CLR中手工装载和运行程序集。

    在codeproject上有一篇文章更加详细全面的讲述了通过vc++ clr和托管代码的互操作:http://www.codeproject.com/Articles/35041/Mixing-NET-and-native-code

  • 相关阅读:
    .NET 开源框架
    ORM 开发框架
    C# 文件下载四方法
    用ASP.net判断上传文件类型的三种方法
    站在十字路口的程序媛,该如何选择?
    突然的烦恼
    Request获取url信息的各种方法比较 及 Request.UrlReferrer详解
    JS 获得当前地址栏url
    MvcPager 概述
    Simditor使用方法
  • 原文地址:https://www.cnblogs.com/duanshuiliu/p/2580110.html
Copyright © 2020-2023  润新知