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

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>
            久久久久在线| 美女黄色成人网| 亚洲经典视频在线观看| 中文在线一区| 日韩午夜电影| 久久久女女女女999久久| 亚洲欧美一区二区激情| 欧美精品首页| 欧美mv日韩mv国产网站app| 国产欧美日韩免费| 亚洲性人人天天夜夜摸| 一本一道久久综合狠狠老精东影业| 久久国产精品黑丝| 久久久久久久一区二区三区| 欧美日韩伦理在线免费| 亚洲第一中文字幕| 国语自产精品视频在线看8查询8| 亚洲天堂久久| 亚洲欧美国产一区二区三区| 欧美日韩亚洲综合一区| 最新亚洲一区| 99av国产精品欲麻豆| 欧美凹凸一区二区三区视频| 欧美aⅴ99久久黑人专区| 国产一区日韩二区欧美三区| 欧美在线视频网站| 久久亚洲色图| 激情综合自拍| 美女网站在线免费欧美精品| 老司机午夜精品视频在线观看| 国内精品久久久久久| 久久成人羞羞网站| 久久综合九色综合欧美就去吻 | 欧美亚洲色图校园春色| 亚洲欧美一区二区在线观看| 国产精品乱看| 欧美一区二区精品在线| 久久久久久一区二区三区| 国产一区二区成人久久免费影院| 欧美中在线观看| 老司机一区二区三区| 亚洲国产成人一区| 欧美大尺度在线| 日韩亚洲欧美在线观看| 欧美一区91| 国产综合亚洲精品一区二| 久久综合一区二区| 亚洲精品一区二区三区樱花| 亚洲综合不卡| 一区二区亚洲精品| 久热精品视频在线观看| 亚洲免费观看高清完整版在线观看熊| 亚洲已满18点击进入久久| 国产精品揄拍500视频| 久久久精品tv| 亚洲啪啪91| 欧美在线免费观看| 亚洲国产精品视频| 国产精品久久亚洲7777| 久久成人免费日本黄色| 亚洲人午夜精品免费| 欧美在线精品免播放器视频| 亚洲国产91精品在线观看| 国产精品盗摄一区二区三区| 欧美中文在线视频| 亚洲精品一二三| 久久久久久精| 一区二区三区精品在线| 国外精品视频| 国产精品久久国产精品99gif| 欧美在线观看网站| 亚洲美女av黄| 嫩草影视亚洲| 欧美一级艳片视频免费观看| 亚洲欧洲一区二区三区在线观看| 国产精品免费一区二区三区在线观看 | 亚洲午夜av在线| 狠狠色狠狠色综合| 欧美性猛交xxxx乱大交蜜桃| 久久婷婷av| 性亚洲最疯狂xxxx高清| 亚洲免费观看视频| 欧美国产日韩精品免费观看| 欧美一区二区三区男人的天堂| 亚洲日韩欧美视频一区| 激情视频一区二区三区| 国产精品夫妻自拍| 欧美精品在线网站| 免费亚洲一区| 久久久国产成人精品| 亚洲欧美精品在线观看| 99re热这里只有精品视频| 亚洲成色最大综合在线| 久久精品日韩一区二区三区| 夜夜嗨av一区二区三区四区| 最近看过的日韩成人| 免费欧美日韩| 裸体一区二区三区| 久久五月天婷婷| 久久精品国产清高在天天线| 欧美与黑人午夜性猛交久久久| 亚洲私人影吧| 一区二区三区福利| 一区二区高清在线| 夜夜嗨av一区二区三区四区| 亚洲日本中文字幕区 | 国产亚洲一区在线| 国产欧美三级| 国产精品一区一区| 国产精品麻豆成人av电影艾秋| 欧美日韩视频专区在线播放| 欧美日韩国产成人在线观看| 欧美精品九九| 欧美日韩亚洲高清一区二区| 欧美日本久久| 欧美午夜在线视频| 国产精品久久久一区麻豆最新章节| 欧美性视频网站| 国产精品一香蕉国产线看观看| 国产精品久久夜| 国产日韩精品久久久| 国产中文一区二区| 1000精品久久久久久久久| 亚洲风情亚aⅴ在线发布| 亚洲人成在线观看一区二区| 一区二区三区高清在线| 亚洲欧美日韩精品久久久久| 久久精品30| 欧美a级在线| 亚洲日本aⅴ片在线观看香蕉| 99热在这里有精品免费| 亚洲欧美国产高清| 久久免费高清视频| 欧美另类极品videosbest最新版本| 欧美日韩免费观看中文| 国产伦精品一区二区三区免费| 国产一二精品视频| 亚洲麻豆一区| 亚洲欧美日韩国产一区二区| 久久亚洲国产精品一区二区| 亚洲福利在线看| 亚洲综合国产激情另类一区| 久久久久久亚洲精品中文字幕| 欧美国产激情二区三区| 国产精品一区二区在线观看不卡| 在线观看福利一区| 亚洲欧美日韩精品综合在线观看| 久久精品国产综合精品| 亚洲黑丝一区二区| 午夜精品久久久99热福利| 久久人人97超碰精品888| 欧美三级资源在线| 韩国一区二区三区在线观看| 中文有码久久| 美女视频黄a大片欧美| 艳女tv在线观看国产一区| 久久天堂av综合合色| 欧美亚洲不卡| 亚洲国产精品电影| 久久9热精品视频| 亚洲精品乱码视频| 久久久青草青青国产亚洲免观| 欧美三区在线视频| 亚洲经典三级| 久久一二三国产| 亚洲一区二区在线看| 免费在线观看成人av| 国产一区二区高清不卡| 亚洲视频日本| 亚洲国产综合视频在线观看| 欧美一区二区三区视频在线观看| 欧美日韩亚洲一区二区| 亚洲日本久久| 裸体一区二区三区| 欧美中文字幕视频| 国产精品最新自拍| 午夜精品www| 999在线观看精品免费不卡网站| 久久久久欧美精品| 国产综合久久久久久鬼色| 香蕉成人伊视频在线观看| 日韩一级成人av| 欧美精品久久天天躁| 亚洲国产精品久久久久秋霞影院 | 翔田千里一区二区| 中国成人在线视频| 欧美日韩亚洲系列| 亚洲视频福利| 亚洲伦理自拍| 欧美日韩中文字幕在线视频| 亚洲精品国产精品乱码不99| 欧美国产日韩在线观看| 久久伊人免费视频| 136国产福利精品导航网址应用 | 免费国产自线拍一欧美视频| 亚洲第一精品夜夜躁人人躁 | 欧美mv日韩mv国产网站| 久久久久久亚洲精品中文字幕| 激情自拍一区| 欧美成熟视频|