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

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 閱讀(1048) 評論(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>
            亚洲午夜在线观看视频在线| 一卡二卡3卡四卡高清精品视频| 欧美影院午夜播放| 欧美午夜视频一区二区| 欧美日本亚洲视频| 欧美成人精品一区二区| 久久天天躁狠狠躁夜夜av| 欧美一区二区黄色| 在线亚洲观看| 亚洲一级影院| 欧美一区二区视频在线观看2020| 亚洲一区二区三| 久久精品成人| 欧美成人日韩| 欧美日韩中文字幕综合视频| 国产乱子伦一区二区三区国色天香| 国产视频一区欧美| 亚洲第一黄色| 亚洲一区二区视频在线| 久久国产精品亚洲77777| 麻豆国产va免费精品高清在线| 欧美黄色小视频| 亚洲在线视频观看| 免费观看成人| 国产精品一区二区久激情瑜伽| 亚洲国产欧美一区二区三区久久| 在线亚洲免费视频| 米奇777在线欧美播放| a91a精品视频在线观看| 久久久人成影片一区二区三区 | 亚洲伦理在线| 午夜精品视频在线| 亚洲电影免费观看高清完整版在线| 亚洲国产精品久久久久| 亚洲欧美国产77777| 欧美激情精品久久久久久黑人| 国产精品乱子久久久久| 亚洲精品在线观看免费| 麻豆av一区二区三区| 午夜欧美不卡精品aaaaa| 欧美日韩精品欧美日韩精品一| 一区在线播放视频| 午夜精品久久久久| 亚洲巨乳在线| 欧美成人一区二区三区在线观看 | 一本色道久久88综合亚洲精品ⅰ| 欧美在线国产| 亚洲天堂av综合网| 欧美日韩1234| 99re6热在线精品视频播放速度| 久久在线精品| 欧美一区二区视频网站| 国产精品免费视频观看| 亚洲视频图片小说| 亚洲精品人人| 欧美激情一区二区在线 | 亚洲免费观看高清完整版在线观看| 裸体一区二区| 久久9热精品视频| 中文国产一区| 国产精品国产三级国产专播精品人| 亚洲精品视频在线| 亚洲第一区在线| 欧美大片va欧美在线播放| 91久久精品国产| 亚洲日本欧美日韩高观看| 欧美激情精品| 亚洲专区在线视频| 亚洲制服欧美中文字幕中文字幕| 国产精品日韩欧美一区| 欧美一区二区三区精品| 午夜精品福利视频| 伊人狠狠色丁香综合尤物| 免费不卡在线观看| 欧美激情91| 亚洲欧美亚洲| 久久久久国产精品www| 最新日韩中文字幕| 99视频+国产日韩欧美| 国产欧美 在线欧美| 久久在线视频| 欧美日韩免费在线| 久久超碰97人人做人人爱| 久久久久久自在自线| 亚洲乱码国产乱码精品精天堂| 日韩视频中文| 好看的亚洲午夜视频在线| 亚洲第一久久影院| 国产九九精品| 亚洲国产日韩欧美在线图片 | 国产精品久久久久久久午夜| 久久成人亚洲| 欧美黄色片免费观看| 欧美一区二区视频在线| 久久久青草婷婷精品综合日韩| 日韩亚洲欧美成人一区| 亚洲免费网址| 日韩亚洲欧美精品| 久久久久欧美精品| 亚洲一区二区三区精品在线观看| 欧美一区二区三区四区视频| 亚洲精品一区二区三区av| 亚洲欧美日韩区| 99国产精品国产精品毛片| 香蕉久久一区二区不卡无毒影院 | 另类春色校园亚洲| 国产精品啊v在线| 亚洲成色精品| 激情久久久久久| 亚洲一区二区三区国产| 亚洲国产天堂网精品网站| 亚洲女爱视频在线| 一区二区三区你懂的| 麻豆精品视频在线| 久久精品观看| 国产农村妇女毛片精品久久麻豆| 亚洲人成人77777线观看| 精东粉嫩av免费一区二区三区| 欧美日韩影院| 欧美大色视频| 国产一区99| 亚洲一区二区在线| 99re6这里只有精品| 女女同性女同一区二区三区91| 久久久99国产精品免费| 国产精品美腿一区在线看 | 久久综合九色欧美综合狠狠| 欧美日韩一区二区三区在线看| 欧美成人网在线| 黄网动漫久久久| 久久不见久久见免费视频1| 午夜国产精品视频| 国产精品久久网| 亚洲少妇中出一区| 亚洲欧美日韩国产综合| 国产精品成人aaaaa网站| 亚洲毛片在线| 在线亚洲高清视频| 国产精品成人观看视频免费| 国产精品99久久久久久久女警| 亚洲欧美视频在线观看视频| 国产精品久久国产精品99gif| 一区二区日本视频| 亚洲欧美一区二区视频| 国产精品一区一区三区| 亚洲欧美激情视频| 久久精品在线视频| 在线观看日产精品| 欧美激情一区二区久久久| 亚洲三级视频| 亚洲专区国产精品| 国产日韩欧美亚洲| 久久久久久电影| 亚洲国产精品第一区二区| 一本大道久久a久久综合婷婷| 欧美视频亚洲视频| 性做久久久久久免费观看欧美| 开心色5月久久精品| 亚洲激情婷婷| 国产精品九九| 久久av资源网站| 亚洲第一黄网| 亚洲欧美国产毛片在线| 国产亚洲制服色| 欧美成人免费网站| 亚洲主播在线播放| 欧美不卡视频一区| 亚洲一二三四区| 在线不卡中文字幕播放| 欧美日韩国产在线| 欧美一区二区三区播放老司机| 欧美国产视频一区二区| 亚洲一区欧美二区| 亚洲国产成人高清精品| 国产精品www| 久久综合久久综合九色| 国产精品99久久久久久久女警| 美女视频黄免费的久久| 亚洲午夜国产成人av电影男同| 激情婷婷久久| 欧美视频在线观看免费| 狼人社综合社区| 亚洲欧美激情在线视频| 亚洲国产精品传媒在线观看| 久久狠狠亚洲综合| 一区二区欧美日韩| 有码中文亚洲精品| 国产欧美欧洲在线观看| 欧美激情91| 亚洲国产精品高清久久久| 欧美午夜精品伦理| 美女精品一区| 欧美专区亚洲专区| 一卡二卡3卡四卡高清精品视频| 欧美成人有码| 久久一区二区三区四区五区| 欧美一区二区三区的| 亚洲欧美日韩国产成人| 一区二区三区日韩欧美| 亚洲精品小视频|