Click here to Skip to main content
Click here to Skip to main content

Unmanaged to Managed Calls

, 3 Apr 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
Call managed code from unmanaged code


If you're developing in a pure .NET environment count yourself lucky. Many of us are still working with languages that, nicely put, are somewhat less than recent. Many have vivid memories of working with software like FoxPro 2.6 which is roughly 10 years old. Unfortunately, in these environments starting over isn't always possible, and so integration of new technology is often a necessity. It can often save development time, provide more robust solutions, increase efficiency and speed, or even preserve your sanity when you're asked to modify that 'particular' application.

One such integration solution is to make your .NET libraries available to existing code through the use of exported functions which reside in a managed C++ bridge dll. In many instances this solution proves adequate and even simpler than other such techniques using COM and other facilities that may or may not be available to you.

The .NET Library

The first thing to do is to develop a .NET library for your required task. There are a variety of ways to expose your .NET solution but the simplest is probably via a class library which is the method used here. Keep in mind that you'll need to provide access to this library through your bridge dll. You may be fortunate enough to be able to expose that library through a single function call (i.e. 'object.do_this' ). However, you may need to preserve state between your calling application and your library, using handles, argument passing, etc.

A tip for those of you unfamiliar with the conversion between managed and unmanaged types; you may want to increase your effort to minimize arguments to the functions which will be called by your bridge dll. Minimizing arguments can often save headaches. Conversion of arguments from unmanaged to managed types and back again (if arguments are begin returned) can be one of the most time consuming parts of the process.  You may be using char *'s, CStrings, arrays, etc. They each have their own intricacies.  Once you've done it a few times though it becomes less of an issue.

The Bridge

The bridge is simply a managed C++ dll in which you export functions with the familiar dllexport attribute. From this dll you'll access your .NET library. Once you've included your .NET dll with the #using directive and optionally imported the namespace, the facilities in your .NET library are available to use. You may need only a single exported function here to provide access to your library, or you may need several. You might want to keep your bridge dll as simple as possible, a bridge only. However, you may want to provide facilities within the bridge specific to the interaction between the calling application and the library. This may provide a more elegant solution for those attempting to implement isolation and data hiding techniques.

The Calling Application

The calling application simply requires the ability to load a dll and make calls to exported functions. The example given in the source is a simple unmanaged C++ console application. It makes calls to several bridge functions and prints the output to the console window. 

The rest of the details are left to the source code which can be downloaded above. The process is relatively simple and so the source included should provide more than enough detail to get you started. Coordinating 3 projects during the debugging process can be tricky so they have all been included in a single solution with a common output directory (/common) in the root of the solution. The bridge dll and console (calling) application build debug output to the common directory. However, the vb.NET library build will not do this so you will need to copy that build to the common directory. All of the paths in the solution are relative, but be sure to check those if you encounter any problems, especially those related to dlls not being loaded, etc.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Michael Combs
United States United States
Michael has been developing software for about 19 years primarily in C#, C/C++, Fortran, and Visual Basic. His previous experience includes Internet data services (communication protocols, data storage and GIS) for the mortgage industry, oil platform instrumentation and explosives simulation and testing. He holds a B.S. in astrophysics and computer science. He is currently working for Global Software in Oklahoma City developing law enforcement and emergency services related software.

Comments and Discussions

GeneralDeployment problem! Pinmembersam2519-Jan-10 15:36 
GeneralSending byte array from unmanaged to managed C++ PinmemberMember 476777810-Aug-09 22:21 
GeneralNice but how about already allocated Managed Object Pinmembernawash11-Jun-09 6:41 
GeneralModified version of bridge program for C++/CLI, for Visual Studio 2005/2008 PinmemberRenniePet8-May-08 4:09 
This article is a very good introduction to the methods that can be used to call C# (or other managed code) from unmanaged C++. It is just unfortunate that it uses the old MC++ syntax instead of the new C++/CLI syntax introduced with Visual Studio 2005.
Here is my attempt at translating the program to the new syntax. Hope I've got it right. Please let me know if I've misunderstood something.
// This is the main DLL file for the unmanaged to managed bridge.
// This version is converted from MC++ (C++ with Managed Extensions) to C++/CLI, the new syntax that came with Visual Studio 2005.
// The old versions of the converted statements have been kept as comments for comparison purposes.
// For more information see
// There are also a few other minor changes in this version.
#include "stdafx.h"
#include "Bridge.h"
extern "C" {
#include <string.h>
#using "dotNetAssembly\bin\dotNetAssembly.dll"
using namespace System;
using namespace dotNetAssembly;
extern "C"
 __declspec(dllexport) int __cdecl bridge_function_int(int input) 
	//mcDotNetClass __gc *DotNetObject;
	mcDotNetClass^ DotNetObject;
	//DotNetObject = new mcDotNetClass;
	DotNetObject = gcnew mcDotNetClass;
 	return DotNetObject->test_integer(input);
 __declspec(dllexport) char *__cdecl bridge_function_string(char *input, int buflen) 
	//String __gc *managed_input = new String(input);
	String^ managed_input = gcnew String(input);
	//mcDotNetClass __gc *DotNetObject;
	mcDotNetClass^ DotNetObject;
	//DotNetObject = new mcDotNetClass;
	DotNetObject = gcnew mcDotNetClass;
	//char tmp __gc[] = System::Text::Encoding::UTF8->GetBytes(DotNetObject->test_string(input));
	array<unsigned char>^ tmp = System::Text::Encoding::UTF8->GetBytes(DotNetObject->test_string(managed_input));
	//char __pin *value = &tmp[0];
	pin_ptr<unsigned char> value = &tmp[0];
	//strncpy(input, value, buflen);
	strncpy_s(input, buflen, (const char*) value, buflen);
	return input;
  __declspec(dllexport) int __cdecl bridge_function_array(int *values, int len) 
	//Array __gc *managed_values;
	Array^ managed_values;
	//mcDotNetClass __gc *DotNetObject;
	mcDotNetClass^ DotNetObject;
	//managed_values = Array::CreateInstance(__typeof(System::Int32),len);
	managed_values = Array::CreateInstance(System::Int32::typeid, len);
	for (int i = 0; i < len; i++) 
		//managed_values->SetValue(__box(values[i]), i);	
		managed_values->SetValue(values[i], i);	
	//DotNetObject = new mcDotNetClass;
	DotNetObject = gcnew mcDotNetClass;
	return DotNetObject->test_array(managed_values);
QuestionAdditional Dependencies PinmemberBarry.Voce2-May-08 3:35 
Generalunhandled exception Pinmembersetori8811-Mar-08 19:27 
GeneralRe: unhandled exception Pinmembersetori8812-Mar-08 17:57 
GeneralRe: unhandled exception PinmemberMark Horton25-Jun-09 10:44 
GeneralRe: unhandled exception Pinmembernegm_phlestin19-Jun-10 23:00 
GeneralRe: unhandled exception Pinmembernegm_phlestin20-Jun-10 4:54 
GeneralRe: unhandled exception Pinmemberfastfred200025-Jan-11 23:08 
GeneralSmart device problem PinmemberBeorne20-Jan-08 23:48 
Generalwindows has triggered a breakpoint... PinmemberInstallerGuy10-Sep-07 19:05 
GeneralCalling from MFC PinmemberUAVonix21-May-07 5:43 
GeneralThanks Pinmemberwangjfcn11-Mar-07 18:13 
GeneralUser Breakpoint error Pinmemberlarstbone20-Jan-06 6:25 
GeneralLinking problem - tip not mentioned in article. PinmemberMatthew677617-Jan-06 7:42 
GeneralSimple, good... But does it support dotnet objects viz Collection classes etc. PinmemberKrishnk25-Oct-05 8:51 
GeneralRe: Simple, good... But does it support dotnet objects viz Collection classes etc. PinmemberEmil S27-Sep-06 21:21 
GeneralThanks ! PinmemberNiFF11-Oct-05 6:17 
GeneralSTAThread Pinsussf_x19-Aug-05 0:25 
GeneralRe: STAThread Pinsussf_x19-Aug-05 10:11 
QuestionHow can I convert a Gdiplus.Graphic* to System.Drawing.Graphics*? Pinsussananymous24-Jan-05 21:14 
GeneralUsing with Powerbuilder 6.5 Pinmembervmalenkov2-Apr-04 12:17 
GeneralRe: Using with Powerbuilder 6.5 Pinmembertangts17-May-04 17:03 
GeneralRe: Using with Powerbuilder 6.5 PinmemberPuneet Vedi28-Feb-07 7:18 
GeneralMFC caller PinmemberProkopis4-Feb-04 3:55 
GeneralRe: MFC caller PinsussAnne _kri8-Jun-05 23:29 
GeneralUsing Visual Studio .NET 2003 Pinmembercotan12-Dec-03 2:38 
GeneralRe: Using Visual Studio .NET 2003 Pinmembermordy20-Dec-03 12:35 
GeneralRe: Using Visual Studio .NET 2003 Pinmembercotan21-Dec-03 5:17 
GeneralRe: Using Visual Studio .NET 2003 Pinmembermordy22-Dec-03 0:17 
GeneralRe: Using Visual Studio .NET 2003 PinsussGavin Stevens28-Jan-04 16:40 
GeneralRe: Using Visual Studio .NET 2003 Pinmemberpkhc11-Mar-04 2:06 
GeneralNice PinsussRogerw8-Apr-03 22:11 
GeneralRe: Nice PinmemberMichael Combs9-Apr-03 5:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150327.1 | Last Updated 4 Apr 2003
Article Copyright 2003 by Michael Combs
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid