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

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>
            久久蜜臀精品av| 日韩视频不卡| 国产精品成人免费视频| 噜噜噜久久亚洲精品国产品小说| 一个色综合av| 亚洲黄色免费| 久久深夜福利免费观看| 午夜精品久久久久| 中日韩高清电影网| 日韩午夜精品| 亚洲日本乱码在线观看| 伊伊综合在线| 国产日韩欧美综合精品| 国产精品mv在线观看| 欧美精品自拍偷拍动漫精品| 久久一本综合频道| 久久精品日韩| 久久久精品性| 久久精品国产视频| 久久激情五月激情| 久久er精品视频| 午夜宅男久久久| 亚洲欧美国产另类| 香港成人在线视频| 亚洲欧美日韩在线综合| 亚洲综合欧美日韩| 亚洲一区二区三区在线看| 正在播放亚洲| 亚洲深夜福利视频| 亚洲一区欧美| 亚洲欧美成人网| 亚洲欧洲av一区二区| 亚洲欧美日韩爽爽影院| 午夜在线视频一区二区区别| 欧美亚洲一区| 久久99伊人| 卡通动漫国产精品| 欧美大片免费看| 欧美另类视频| 欧美性事免费在线观看| 国产精品久久97| 国产免费亚洲高清| 国内精品亚洲| 在线观看成人av| 亚洲人成啪啪网站| 中文亚洲免费| 亚洲欧美国产另类| 久久久国产午夜精品| 美女被久久久| 亚洲大胆在线| 中国女人久久久| 午夜精品久久一牛影视| 久久久av网站| 欧美日韩国产区| 国产欧美日韩视频| 在线成人h网| 亚洲美女一区| 性做久久久久久久久| 久久久久久一区| 亚洲国产精品999| 亚洲天天影视| 久久久久成人精品| 欧美日韩亚洲一区二区三区四区| 国产精品永久免费视频| 伊人久久大香线| 一区二区三区黄色| 久久国内精品自在自线400部| 欧美 日韩 国产 一区| 一区二区三区不卡视频在线观看| 性欧美暴力猛交另类hd| 欧美xxxx在线观看| 国产精品日日摸夜夜添夜夜av| 加勒比av一区二区| 一区二区三区四区五区视频| 久久精品国产第一区二区三区最新章节| 久久午夜影视| 日韩一区二区精品| 久久九九有精品国产23| 国产精品qvod| 亚洲精品美女91| 久久精品视频免费播放| 亚洲人成在线播放| 欧美伊人久久| 欧美视频在线观看一区| 在线日韩av| 欧美一级网站| 亚洲剧情一区二区| 久久久国产成人精品| 欧美亚洲成人免费| 亚洲欧洲在线视频| 久久久久久久综合狠狠综合| 日韩视频在线一区二区三区| 久久久99精品免费观看不卡| 欧美午夜片在线观看| 亚洲国产小视频| 久久久久一区二区三区四区| aa级大片欧美三级| 免费永久网站黄欧美| 狠狠噜噜久久| 香蕉免费一区二区三区在线观看 | 韩国成人精品a∨在线观看| 一区二区欧美在线| 欧美成人免费视频| 欧美在线一二三区| 国产精品亚洲综合久久| 亚洲一区二区三区精品视频| 免费一级欧美在线大片| 欧美一区二区三区四区夜夜大片| 欧美日韩一二三四五区| 亚洲精品国偷自产在线99热| 另类av导航| 欧美一区激情视频在线观看| 国产精品美女久久久久av超清 | 亚洲美女少妇无套啪啪呻吟| 久久亚洲欧美| 精品动漫3d一区二区三区免费| 午夜精品久久久久久久男人的天堂| 亚洲精品在线观看免费| 欧美激情久久久| 亚洲精品国产精品国自产观看浪潮| 久久一区亚洲| 久久精品成人| 在线免费观看日韩欧美| 免费看的黄色欧美网站| 久久精品夜色噜噜亚洲aⅴ| 国产亚洲一区在线| 久久久青草婷婷精品综合日韩| 午夜在线精品偷拍| 国产亚洲综合在线| 久久一区二区三区四区| 久久影音先锋| 亚洲国产成人91精品| 亚洲成人在线网站| 欧美国产日本韩| 99国产精品视频免费观看一公开| 91久久在线播放| 欧美日本一区二区三区| 亚洲一区二区三区中文字幕| 在线视频一区观看| 国产精品午夜国产小视频| 欧美一区二区视频97| 欧美一区二区三区视频在线| 国内精品久久久久久| 毛片av中文字幕一区二区| 美日韩精品免费观看视频| 日韩视频国产视频| 一本久久综合亚洲鲁鲁| 国产九区一区在线| 玖玖视频精品| 欧美激情精品久久久久久蜜臀| 亚洲天堂成人在线视频| 午夜精品久久久久久| 在线观看欧美激情| 91久久综合亚洲鲁鲁五月天| 国产精品久久久久一区二区| 久久久精品日韩欧美| 免费成人黄色片| 中文精品视频一区二区在线观看| 亚洲免费网址| 亚洲国产精彩中文乱码av在线播放| 亚洲激情国产| 国产精品一区二区三区四区| 狂野欧美一区| 欧美精品午夜视频| 久久精品91久久香蕉加勒比| 久久综合久色欧美综合狠狠| 一区二区久久久久久| 欧美一区三区二区在线观看| 亚洲国产二区| 亚洲天堂黄色| 亚洲欧洲综合| 亚洲综合成人婷婷小说| 亚洲国产精品一区二区第四页av| 日韩亚洲欧美中文三级| 国产综合在线视频| 99精品视频免费全部在线| 国产亚洲日本欧美韩国| 亚洲乱码日产精品bd| 国产一区二区三区在线播放免费观看 | 国产性色一区二区| 亚洲高清一区二| 国产美女诱惑一区二区| 亚洲国产精品黑人久久久| 国产片一区二区| 亚洲精品婷婷| 在线观看欧美视频| 亚洲一区中文| 一本不卡影院| 久久尤物视频| 久久久999精品免费| 欧美久久在线| 欧美成人一区二区| 国产日产欧美一区| 日韩一级成人av| 亚洲人成在线观看一区二区| 欧美在线视频一区二区三区| 亚洲一区成人| 欧美激情亚洲综合一区| 美女脱光内衣内裤视频久久网站| 国产精品免费视频观看|