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

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) 評(píng)論(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>
            亚洲天堂av综合网| 久久精品一区蜜桃臀影院| 夜夜嗨av一区二区三区四区 | 国产精品久久999| 亚洲精品一区二区三区樱花| 老司机精品导航| 一区二区三区精品视频在线观看| 久久久亚洲精品一区二区三区| 国产伦精品一区二区三区免费迷| 一本久道久久综合中文字幕| 91久久精品一区二区别| 欧美一区亚洲一区| 国产一区二区三区四区| 欧美中日韩免费视频| 亚洲伊人伊色伊影伊综合网| 国产精品你懂的| 午夜精品一区二区三区在线| 亚洲免费婷婷| 国产在线观看精品一区二区三区 | 久久精品一区二区三区不卡牛牛| 国产欧美日韩亚州综合| 欧美在线在线| 久久本道综合色狠狠五月| 激情综合久久| 美女视频网站黄色亚洲| 欧美成年人网| 在线亚洲美日韩| 亚洲一区欧美| 在线观看的日韩av| 亚洲国产欧美久久| 欧美三区美女| 久久精品日韩欧美| 久久久水蜜桃| 日韩亚洲综合在线| 9l视频自拍蝌蚪9l视频成人| 亚洲国产精品欧美一二99| 欧美日韩免费观看一区| 亚洲影院免费| 午夜在线成人av| 亚洲精品久久在线| 亚洲一区二区三区四区五区黄| 国产嫩草一区二区三区在线观看 | 欧美在线啊v| 亚洲国产精品激情在线观看| 亚洲福利视频一区| 欧美午夜精品理论片a级按摩| 欧美一区二区福利在线| 久久综合伊人77777麻豆| 99亚洲视频| 欧美一区二区网站| 亚洲精品四区| 午夜精品一区二区在线观看 | 欧美在线日韩精品| 美女久久一区| 性欧美精品高清| 欧美激情网站在线观看| 久久av二区| 欧美日韩精品一区二区三区| 欧美制服第一页| 欧美人体xx| 老鸭窝毛片一区二区三区| 欧美日韩综合在线免费观看| 久久久久国色av免费看影院| 欧美三区在线| 91久久亚洲| 激情综合电影网| 亚洲欧美综合另类中字| 一区二区三区成人| 久久综合九色综合久99| 亚洲欧美福利一区二区| 欧美成人在线网站| 久久中文精品| 国产欧美日韩精品在线| 亚洲激情校园春色| 在线成人亚洲| 午夜精品久久久久久久99热浪潮 | 亚洲国产成人91精品| 亚洲欧美日韩视频二区| 中日韩高清电影网| 欧美成年人网| 欧美激情欧美激情在线五月| 国产亚洲欧美在线| 99精品视频免费在线观看| 亚洲人体一区| 欧美成人一区二免费视频软件| 久久久久久国产精品mv| 国产伦精品免费视频 | 欧美久久久久| 老妇喷水一区二区三区| 国产真实精品久久二三区| 亚洲一区二区视频在线观看| 亚洲专区在线视频| 亚洲国产精品电影| 男女精品网站| 国产视频欧美| 欧美一区二区成人6969| 欧美一区二区视频免费观看 | 亚洲黄色一区二区三区| 久久亚洲春色中文字幕| 欧美成人第一页| 亚洲福利视频一区二区| 另类天堂视频在线观看| 嫩草国产精品入口| 亚洲电影av在线| 欧美大片免费观看| 亚洲国产欧美国产综合一区| 99在线精品免费视频九九视| 欧美日韩一区二区视频在线观看| 亚洲日本在线观看| 99精品欧美一区| 欧美日韩亚洲视频| 亚洲一区二区三区精品视频 | 亚洲影院免费| 欧美一区二区三区成人 | 欧美二区视频| 在线视频一区观看| 国产精品人人做人人爽| 欧美一区二区三区久久精品茉莉花 | 欧美人成网站| 亚洲午夜精品一区二区| 欧美有码视频| 亚洲国产精品久久久久| 欧美激情影音先锋| 亚洲一区二区三区高清| 欧美国产日韩一区二区在线观看 | 国产精品99免视看9| 午夜精品免费视频| 欧美第一黄色网| 亚洲一区网站| 亚洲福利视频网| 国产精品久久久久久亚洲毛片| 亚洲欧美激情精品一区二区| 欧美成人黄色小视频| 亚洲一区二区三区视频播放| 国产精品视频一| 欧美国产日韩xxxxx| 亚洲图片欧美午夜| 麻豆久久久9性大片| 一区二区日韩免费看| 国内综合精品午夜久久资源| 欧美日韩99| 亚洲一区美女视频在线观看免费| 久色成人在线| 亚洲午夜免费视频| 激情综合久久| 欧美日韩成人精品| 欧美综合第一页| 亚洲少妇诱惑| 欧美黄色aaaa| 午夜免费在线观看精品视频| 影音先锋在线一区| 午夜精品久久久99热福利| 欧美亚洲免费高清在线观看| 国产专区精品视频| 欧美午夜精品久久久| 美国十次了思思久久精品导航| 亚洲精品久久视频| 久久精品免费看| 亚洲欧美伊人| 日韩视频专区| 国产日韩精品一区观看| 欧美三区在线| 欧美激情视频一区二区三区免费 | 亚洲国产婷婷| 久久精品视频在线播放| 亚洲国产一区二区a毛片| 国产精品自拍三区| 欧美日韩综合网| 欧美高清不卡在线| 久久亚洲国产精品一区二区| 欧美一区影院| 欧美在线日韩在线| 亚洲女女女同性video| 亚洲三级性片| 欧美激情a∨在线视频播放| 久久精品亚洲乱码伦伦中文| 亚洲最新合集| 在线亚洲欧美| 亚洲国产激情| 韩国av一区| 国内免费精品永久在线视频| 韩国精品久久久999| 国产精自产拍久久久久久蜜| 欧美激情第8页| 亚洲一区视频| 亚洲欧美不卡| 亚洲一区二区三区免费观看| 欧美影视一区| 午夜一区二区三视频在线观看| 亚洲一区二区三区免费在线观看 | 欧美日本视频在线| 欧美极品色图| 美女成人午夜| 欧美精品1区| 欧美精选在线| 国产精品大片| 国产午夜精品视频| 国产日产欧美a一级在线| 欧美中文字幕久久| 久久国产精品99精品国产|