青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 17,  comments - 2,  trackbacks - 0

Calling Managed Code from Unmanaged Code and vice-versa

By TarunNeo

This article shows you how to call managed code from unmanaged code and also the other way round.
C++/CLI, VB, VC7.1, C++, Windows, .NET, .NET 1.1VS.NET2003, Visual Studio, Dev

Posted21 Mar 2005
Updated21 Mar 2005 
Views78,822
Bookmarked50 times
22 votes for this Article.
Popularity: 5.47 Rating: 4.07 out of 5
0 votes, 0.0%
1
1 vote, 4.5%
2
3 votes, 13.6%
3
8 votes, 36.4%
4
10 votes, 45.5%
5

Introduction

.NET framework is one of the better development and execution environments for software these days. But there is a very huge amount of software components already developed and being developed out of unmanaged code. So, there needs to be an easy way for managed code to call the unmanaged code and the other way round.

I have seen some articles on this, but I did not find them giving a complete solution of what I was looking for. So here is one.

Background

Microsoft lets you call COM code from .NET code using RCW (Runtime Callable Wrappers). The RCW, a managed wrapper code, wraps the COM component. The .NET code then interacts with the RCW which in turn interacts with the COM component inside it. The reverse communication can be done using CCW (COM callable wrapper).

This article shows a way of manually creating a wrapper. It was fairly easy to call the unmanaged code from the managed code but not the other way around.

Code

The code that I have specified below consists of:

  • Unmanaged class: UnManaged_Class
  • Managed Wrapper class: Managed_Wrapper_Class

This class wraps the unmanaged class. This means that it “contains” an object of the unmanaged type which it uses to call the exposed methods in the unmanaged type.

  • Managed code: Managed_Class

This is how the managed code calls the unmanaged code:

For every exposed method in the unmanaged class, there should be a corresponding method in the Managed_Wrapper_Class. The managed code instantiates an object of theManaged_Wrapper_Class and calls the exposed methods in that class using this instance. These methods in the Managed_Wrapper_Class then call the corresponding methods in the unmanaged code. This is done using pInner as shown in the code:

//

/*//////////////////////////////////////////////////
//Unmanaged_Class.cpp
//////////////////////////////////////////////////*/


#ifndef UNMANAGED
#define UNMANAGED

class Unmanaged_Class
{
public:

    Unmanaged_Class();
    
    /*This is the method that is to be called from Managed code*/
    void methodToBeCalledInUnmanaged(int data);
};

#endif


*//////////////////////////////////////////////////

//Unmanaged_Class.cpp

//////////////////////////////////////////////////*/


#include "StdAfx.h"

#using <mscorlib.dll>
#include "Unmanaged.h"


Unmanaged_Class::Unmanaged_Class()
{
}

void Unmanaged_Class::methodToBeCalledInUnmanaged(int data)
{
    /*Here is the place where the Managed Wrapper code is called. */
    scallback(data+1);
}


/*//////////////////////////////////////////////////
//Managed_Wrapper.h 
//////////////////////////////////////////////////*/

#pragma once

#include "stdafx.h"

#using <mscorlib.dll>
#include "Unmanaged.h"


using namespace System::Runtime::InteropServices;
using namespace System;

namespace Managed_Wrapper
{

    /*Managed Wrapper Class */
    public __gc class Managed_Wrapper_Class
    {
    public: 
    
        //constructor

        Managed_Wrapper_Class();

        /* pInner is used to invoke the exposed 
        methods in the unmanaged class. */
        Unmanaged_Class * pInner; 


        /* An exposed function corresponding 
        to the exopsed function in Unmanaged*/
        void CallUnmanaged(int data);

    };
}

/*//////////////////////////////////////////////////
//Managed_Wrapper.cpp
//////////////////////////////////////////////////*/

#include "stdafx.h"

#include "Managed_Wrapper.h"

#using <mscorlib.dll>

namespace Managed_Wrapper
{
    Managed_Wrapper_Class::Managed_Wrapper_Class(void)
    {
        /* define the pInner object */
        pInner = new Unmanaged_Class();
    }


    void Managed_Wrapper_Class::CallUnmanaged(int data)
    {
        pInner->methodToBeCalledInUnmanaged (data);
    }

}
'/*//////////////////////////////////////////////////

'//Managed Code

'//VB.NET code

'//////////////////////////////////////////////////*/



'Import the Managed Wrapper Namespace

Imports Managed_Wrapper


'Create an instance of the Managed Wrapper class.

Dim forwardCaller As Managed_Wrapper_Class = New Managed_Wrapper_Class


'To call a method in the Managed_Wrapper_Class. This method in 

'turn will call the method in the unmanaged code

forwardCaller.CallUnmanaged(nudNumber.Value)

This was the easy part. Now is the hard part. Calling managed code from the unmanaged code.

The unmanaged code has a function pointer. The address of the function pointer is the address of a method in the managed wrapper class. Also, the function pointer is initialized by the wrapper class and not in the unmanaged code. So this way, when the function pointer is called, the method in the managed wrapper code is called. Half of the task is done. The way of assigning the function pointer in the unmanaged code is not easy because the function has to point to a method which is managed. So, we use the wrapper delegate struct as shown in the code. Then convert this delegate struct to a function pointer of unmanaged type using Marshal::StructureToPtr (_Instance_Of_Delegate_Wrapper, &type_unmanaged_functionptr, false);

The managed wrapper code declares a delegate (a .NET way of a function pointer). The delegate is instantiated by the managed code. So when the method in the managed wrapper class is called (by the unmanaged code), it in turn calls the delegate in the same class (which is initialized by the managed code). As the delegate points to a function in the managed code, the method in the managed code gets called. This was the hard part.

/*///////////////////////////////////////////////////
/*Unmanaged_Class.h */
///////////////////////////////////////////////////*/


#ifndef UNMANAGED
#define UNMANAGED

#using <mscorlib.dll>

typedef void (*w_CallBack) (int status);

class Unmanaged_Class
{
public:

 Unmanaged_Class();
 w_CallBack scallback;

 /* To set the callback function. The address in ptr2F will be the
 address of a method in the Managed Wrapper class and will be assigned
 there. In this case it will be address of ActualMethodInWrapper(int );*/
 void setCallBackInUnmanaged(w_CallBack ptr2F);

 /*This is the method that is to be called from Managed code*/
 void methodToBeCalledInUnmanaged(int data);
};

#endif
/*///////////////////////////////////////////////////
//Unmanaged_Class.cpp
///////////////////////////////////////////////////*/

#include "StdAfx.h"

#using <mscorlib.dll>
#include "Unmanaged.h"


Unmanaged_Class::Unmanaged_Class()
{
}

void Unmanaged_Class::setCallBackInUnmanaged(w_CallBack ptr2F)
{
 /*scallback now points to ActualMethodInWrapper(int) in
 Managed_Wrapper_Class*/
 scallback = ptr2F;
}

void Unmanaged_Class::methodToBeCalledInUnmanaged(int data)
{
 /*Here is the place where the Managed Wrapper code is called. */
 scallback(data+1);
}
/*///////////////////////////////////////////////////
//Managed_Wrapper.h
///////////////////////////////////////////////////*/

#pragma once

#include "stdafx.h"

#using <mscorlib.dll>
#include "Unmanaged.h"


using namespace System::Runtime::InteropServices;
using namespace System;

namespace Managed_Wrapper
{

 /*Declare a delegate. It is to be invoked from the unmanaged code*/
 public __delegate void CallbackDelegate(int data);

 /* Declare a wrapping struct that wraps an object of the above 
 declared delegate. The delegate that this struct contains will 
 point to a method that will be called when this delegate is 
 invoked from the unmanaged code*/
 [StructLayoutAttribute( LayoutKind::Sequential, CharSet = CharSet::Ansi )]
 public __gc struct Managed_Delegate_Wrapper
 {
 [MarshalAsAttribute(UnmanagedType::FunctionPtr)]
 CallbackDelegate* _Delegate;
 };

 /*Managed Wrapper Class */
 public __gc class Managed_Wrapper_Class
 {
 public:

 //constructor

 Managed_Wrapper_Class();

 /* pInner is used to invoke the exposed methods in the unmanaged class. */
 Unmanaged_Class * pInner;

 /* Declare an instance of the wrapping struct */
 Managed_Delegate_Wrapper * _Status_Delegate;

 /* A method that will be called when the callback function in the unmanaged
 code is called. It is this method who’s pointer is passed to the unmanaged
 code.*/
 void ActualMethodInWrapper(int );

 /*A delegate type. To be used for calling managed code from here.*/
 __delegate int statusDelegate(int status);

 /*An object of the above delagate type is declared.
 It will be initialized in the managed code.*/
 statusDelegate *statD;

 /* An exposed function corresponding to the exopsed function in Unmanaged*/
 void CallUnmanaged(int data);

 };
}
/*///////////////////////////////////////////////////
//Managed_Wrapper.cpp
///////////////////////////////////////////////////*/

#include "stdafx.h"

#include "Managed_Wrapper.h"

#using <mscorlib.dll>

namespace Managed_Wrapper
{
 Managed_Wrapper_Class::Managed_Wrapper_Class(void)
 {
 /* define the pInner object */
 pInner = new Unmanaged_Class();

 /* define the wrapping struct instance declared in Managed_Wrapper_Class */
 _Status_Delegate = new Managed_Delegate_Wrapper();

 /* This is the actual delegate that is contained in the wraping struct */
 _Status_Delegate->_Delegate = 
   new CallbackDelegate(this, &Managed_Wrapper_Class::ActualMethodInWrapper);

 /* declare a function pointer of the same type as in unmanaged code */
 w_CallBack callback;

 /*convert the wrapping struct to a function pointer of the above type. */
 Marshal::StructureToPtr (_Status_Delegate, &callback, false);

 /* set this function pointer in the unmanaged code using pInner.*/
 pInner->setCallBackInUnmanaged(callback);
 }

 /*This is the method in the Managed_Wrapper_Class that is called
 when the function pointer in the unmanaged code is called.*/
 void Managed_Wrapper_Class::ActualMethodInWrapper(int status)
 {
 /*This method in turn calls the delegate in the managed code.
 The method that statD is actually poiting is specified in the
 managed code itself.*/
 statD(status);
 }

 void Managed_Wrapper_Class::CallUnmanaged(int data)
 {
 pInner->methodToBeCalledInUnmanaged (data);
 }

}
'/*//////////////////////////////////////////////////

'//Managed Code

'//VB.NET code

'//////////////////////////////////////////////////*/


'Import the Managed Wrapper Namespace

Imports Managed_Wrapper

'Create an instance of the Managed Wrapper class.

Dim forwardCaller As Managed_Wrapper_Class = New Managed_Wrapper_Class

'Create an instance of the delegate declared in the Managed Wrapper

'class. Initialize it with the address of the method that is supposed

'to be called when the delegate in the Managed_Wrapper_Class is called

Dim statDelg As New Managed_Wrapper_Class.statusDelegate(AddressOf status_Recd)

'This function gets called when the unmanaged code calls the

'managed wrapper code and which in turn calls the the delegate

'in there

Public Function status_Recd(ByVal status As Integer) As Integer

 'use status for something now. It took so much effort to get it :)

 MessageBox.Show("Status received is " + status.ToString(), "Status" + 
                 " received from the Unmanaged code")

End Function

 'To call a method in the Managed_Wrapper_Class. This method in

 'turn will call the method in the unmanaged code

 forwardCaller.CallUnmanaged(nudNumber.Value)

 'statD is called from the managed code. And statD in turn

 'will call the method status_Recd

 forwardCaller.statD = statDelg

Compiling and Linking

Choose a C++ .NET Class Library project to wrap your unmanaged code and compile it to generate the DLL. Then in your VB.NET code, add a reference to this DLL using Add Reference->Projects (Browse to the DLL). Also you would need to have your Project properties as in the demo project on the top.

Demo

Open the Managed_VBdotNET.sln solution and start it. Bingo.

Summary

I found this technique particularly useful for one of my projects in which I had some code which was already written in C++ and was a good idea to have it written in C++. I needed to add a GUI to it, for which VB.NET was a very straightforward choice. Through this way I could invoke C++ methods through VB.NET and VB.NET methods through C++.

Any suggestions are welcome and will be appreciated. Please feel free to ask any questions.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

TarunNeo


Tarun is a Computer Science Grad. He believes in
".......In between and after is glorious coding"


Occupation:Web Developer
Location:United States United States
posted on 2008-11-14 11:40 BeyondCN 閱讀(1054) 評論(0)  編輯 收藏 引用 所屬分類: .NET
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            性欧美暴力猛交另类hd| 亚洲破处大片| 欧美大片一区二区三区| 先锋影音一区二区三区| 欧美成人视屏| 巨胸喷奶水www久久久免费动漫| 欧美日韩1080p| 欧美国产亚洲视频| 国产一级久久| 亚洲在线中文字幕| 亚洲一区在线视频| 欧美极品一区| 亚洲第一主播视频| 在线成人免费观看| 午夜视频在线观看一区| 亚洲免费小视频| 欧美日韩大片| 亚洲欧洲三级| 日韩一级黄色av| 欧美激情区在线播放| 欧美**人妖| 亚洲福利视频三区| 久久久www成人免费无遮挡大片| 性色av一区二区怡红| 欧美视频免费看| 亚洲精品综合久久中文字幕| 亚洲激情视频网| 美国十次成人| 亚洲国产高清一区| 亚洲精品色婷婷福利天堂| 久热精品视频在线| 欧美成熟视频| 亚洲全部视频| 欧美日韩国产精品| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲日本中文字幕| 欧美日韩国产黄| 亚洲无吗在线| 欧美一级大片在线观看| 欧美一区二区三区喷汁尤物| 国产精品美女主播| 欧美一区二区在线| 免费观看成人鲁鲁鲁鲁鲁视频| 狠狠操狠狠色综合网| 久久夜色精品| 亚洲激情黄色| 亚洲欧美日韩一区| 国产一区二区三区久久久久久久久| 新67194成人永久网站| 久久综合色8888| 亚洲三级免费观看| 国产精品久久久久久久久搜平片 | 欧美在线播放一区| 国产一区在线看| 欧美1区3d| 一区二区三区**美女毛片| 香蕉久久夜色精品国产使用方法| 国产亚洲人成a一在线v站 | 亚洲精品一二| 性色一区二区| 亚洲国产日韩在线| 欧美日韩国产黄| 午夜视频一区在线观看| 亚洲大胆美女视频| 亚洲免费综合| 亚洲日本在线观看| 国产女人水真多18毛片18精品视频| 欧美专区日韩视频| 亚洲美女福利视频网站| 久久国内精品视频| 亚洲毛片av| 国产欧亚日韩视频| 欧美日韩精品在线视频| 久久爱www.| 一区二区三区欧美在线观看| 久久一区亚洲| 午夜精品久久久久久久久久久久| 1000部精品久久久久久久久| 欧美调教视频| 免费短视频成人日韩| 亚洲欧美国产一区二区三区| 欧美大片免费观看| 久久精品国产久精国产爱| 一区二区精品在线观看| 亚洲福利视频一区| 国产一区二区三区精品久久久| 欧美日韩高清不卡| 美女脱光内衣内裤视频久久影院| 亚洲专区国产精品| 亚洲美女在线看| 亚洲国产精品精华液2区45| 久久成人免费电影| 亚洲视频高清| 99re热精品| 亚洲国产精品www| 好吊视频一区二区三区四区| 国产精品爽爽爽| 欧美三日本三级三级在线播放| 欧美大胆成人| 欧美顶级大胆免费视频| 久久九九免费| 久久不射电影网| 欧美一区二区三区四区在线观看地址 | 欧美午夜不卡视频| 欧美福利在线| 欧美成人免费一级人片100| 久久婷婷国产综合尤物精品| 性色一区二区三区| 亚洲欧美日韩综合国产aⅴ| 亚洲图片欧洲图片日韩av| 日韩网站在线| 日韩一区二区免费看| 亚洲片国产一区一级在线观看| 欧美韩日视频| 欧美国产视频在线观看| 欧美激情亚洲| 99re热精品| 一区二区高清视频在线观看| 在线视频精品一| 亚洲一区二区久久| 亚洲欧美成人在线| 欧美一区日韩一区| 久久久久免费| 久久噜噜亚洲综合| 蜜桃久久精品乱码一区二区| 欧美www视频| 欧美日韩精品高清| 国产精品久久久久久久浪潮网站| 国产欧美亚洲一区| 一区二区视频在线观看| 亚洲国产精品视频一区| 99国产精品99久久久久久| 亚洲一区二区三区欧美| 午夜精品在线观看| 久久人人97超碰国产公开结果 | 精品91在线| 亚洲精品女人| 亚洲一区二区网站| 欧美中文字幕在线观看| 久久躁日日躁aaaaxxxx| 亚洲国产另类久久久精品极度| 亚洲欧洲精品一区| 亚洲一区二区欧美| 久久免费99精品久久久久久| 欧美精品一区二区三区很污很色的| 国产精品v欧美精品v日韩 | 国产偷自视频区视频一区二区| 国内精品久久久久影院色| 亚洲国产日韩欧美| 亚洲欧美日本国产专区一区| 久久中文欧美| 日韩视频免费大全中文字幕| 午夜激情久久久| 欧美精品一区二| 国产亚洲一本大道中文在线| 亚洲另类自拍| 久久久久久一区| 亚洲免费观看在线视频| 久久亚洲精品网站| 国产精品久久久久久av下载红粉 | 中文亚洲字幕| 久久久噜噜噜| 亚洲一级免费视频| 欧美成人dvd在线视频| 国产色视频一区| 日韩亚洲在线观看| 美女在线一区二区| 亚洲综合欧美日韩| 欧美日本一区| 亚洲国产视频a| 久久激情网站| 亚洲一区二区四区| 欧美另类专区| 亚洲啪啪91| 美女免费视频一区| 亚洲欧美日韩国产一区| 欧美日韩高清在线播放| 91久久精品www人人做人人爽| 久久se精品一区精品二区| 99综合视频| 欧美精品三级| 亚洲国产三级网| 免费在线国产精品| 欧美中文字幕| 国产日韩av一区二区| 香蕉av777xxx色综合一区| 99av国产精品欲麻豆| 欧美激情一区二区三区在线| 亚洲国产精品999| 麻豆精品国产91久久久久久| 欧美在线1区| 狠狠久久亚洲欧美| 久久久久久久综合日本| 亚洲欧美另类中文字幕| 国产精品尤物| 欧美一区2区三区4区公司二百 | 午夜精品一区二区三区在线播放| 欧美午夜精品久久久久久浪潮| 9l视频自拍蝌蚪9l视频成人| 亚洲精品久久久蜜桃|