Calling Unmanaged Code: Part 1 - simple DLLImport

Environment: [.NET]

The managed world is beautiful. I have all classes I could want in FrameWork. What happens if I want to call some unmanaged code--such as existing C++ code? For instance, I have DLL written in C++, and want use it from C#.

Let's look some code. I have a DLL that exports a function in CDecl convention, that sums two integers:

extern "C" __declspec(dllexport) __cdecl 
                          int sum(int a,int b);

And, of course, I want to reuse this code in C#. There is no "direct" way to call unmanaged code, so you must inform the compiler about it. More specificially, you must tell the compiler about what you want to call, how you want it called, and where its needed code is located:
   [DllImport("TestDll.dll", EntryPoint="sum", 
   ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
   static extern int sum(int a,int b);

Once you've done this, you can then call it like any other normal C# function:

   x=5;
   y=7;
   z=sum(x,y);   // x will receive 12 

Here is full C# client code - tested for Beta2:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

namespace WindowsApplication6
{
   /// <summary>
   /// Summary description for Form1.
   /// </summary>
   public class Form1 : System.Windows.Forms.Form
   {
     private System.Windows.Forms.Button button1;
     private System.Windows.Forms.TextBox textBox1;
     private System.Windows.Forms.Label label1;
     private System.Windows.Forms.TextBox textBox2;
     private System.Windows.Forms.Label label2;
    private System.Windows.Forms.TextBox textBox3;
     /// <summary>
     /// Required designer variable.
     /// </summary> 
     private System.ComponentModel.Container components = null;

     public Form1()
     {
       //
       // Required for Windows Form Designer support
       //
       InitializeComponent();

       //
       // TODO: Add any constructor code after 
       //       InitializeComponent call
     }

     /// <summary>
     /// Clean up any resources being used.
     /// </summary>
     protected override void Dispose( bool disposing )
     {
       if( disposing )
       {
         if (components != null) 
         {
           components.Dispose();
         }
       }
       base.Dispose( disposing );
     }

     #region Windows Form Designer generated code
     /// <summary>
     /// Required method for Designer support - do not modify
     /// the contents of this method with the code editor.
     /// </summary>
     private void InitializeComponent()
     {
       this.button1 = new System.Windows.Forms.Button();
       this.textBox1 = new System.Windows.Forms.TextBox();
       this.label1 = new System.Windows.Forms.Label();
       this.textBox2 = new System.Windows.Forms.TextBox();
       this.label2 = new System.Windows.Forms.Label();
       this.textBox3 = new System.Windows.Forms.TextBox();
       this.SuspendLayout();
       // 
       // button1
       // 
       this.button1.Location = new System.Drawing.Point(64, 192);
       this.button1.Name = "button1";
       this.button1.Size = new System.Drawing.Size(144, 64);
       this.button1.TabIndex = 0;
       this.button1.Text = "call sum";
       this.button1.Click 
             += new System.EventHandler(this.button1_Click);
       // 
       // textBox1
       // 
       this.textBox1.Location = new System.Drawing.Point(40, 120);
       this.textBox1.Name = "textBox1";
       this.textBox1.Size = new System.Drawing.Size(72, 22);
       this.textBox1.TabIndex = 1;
       this.textBox1.Text = "2";
       // 
       // label1
       // 
       this.label1.Location = new System.Drawing.Point(128, 128);
       this.label1.Name = "label1";
       this.label1.Size = new System.Drawing.Size(16, 16);
       this.label1.TabIndex = 2;
       this.label1.Text = "+";
       // 
       // textBox2
       // 
       this.textBox2.Location = new System.Drawing.Point(152, 120);
       this.textBox2.Name = "textBox2";
       this.textBox2.Size = new System.Drawing.Size(56, 22);
       this.textBox2.TabIndex = 3;
       this.textBox2.Text = "3";
       // 
       // label2
       // 
       this.label2.Location = new System.Drawing.Point(224, 120);
       this.label2.Name = "label2";
       this.label2.Size = new System.Drawing.Size(24, 23);
       this.label2.TabIndex = 4;
       this.label2.Text = "=";
       // 
       // textBox3
       // 
       this.textBox3.Location = new System.Drawing.Point(248, 120);
       this.textBox3.Name = "textBox3";
       this.textBox3.Size = new System.Drawing.Size(112, 22);
       this.textBox3.TabIndex = 5;
       this.textBox3.Text = "5";
       // 
       // Form1
       // 
       this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
       this.ClientSize = new System.Drawing.Size(576, 322);
       this.Controls.AddRange(new System.Windows.Forms.Control[] {
                        this.textBox3,
                        this.label2,
                        this.textBox2,
                        this.label1,
                        this.textBox1,
                        this.button1});
       this.Name = "Form1";
       this.Text = "Form1";
       this.ResumeLayout(false);

     }
     #endregion

     /// <summary>
     /// The main entry point for the application.
     /// </summary>
     [STAThread]
     static void Main() 
     {
       Application.Run(new Form1());
     }
     
     #region My Code
     #region Dll Imports
     [DllImport("TestDll.dll", EntryPoint="sum", 
     ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
     static extern int sum(int a,int b);
     #endregion
     #region Button Click Events
     private void button1_Click(object sender, System.EventArgs e)
     {
       textBox3.Text=(int.Parse(textBox1.Text)+
                           int.Parse(textBox2.Text)).ToString();
     }
     #endregion
     #endregion
   }
}

I defined 3 textboxes, where textBox1 and textBox2 are the two operands, and where textBox3 is result. The button1 calls sum() and updates the result. The sum() method is defined as "static extern", which means it is an extern linked functions. It can't be put outside of class, becouse in C# there are no "alone" functions--everyone must belong to a class.

The calling convention is CDecl, because the C++ function is compiled with the __cdecl attribute. ExactSpelling=false tells the compiler to try "decore" the function name with "W" for Unicode or "A" for ANSI.

The button1 Click event parses two arguments from string to int, call to sum() and puts result as string.

Pay attention, you can use normal C++ declaration, without <extern "C">:

/*extern "C"*/ __declspec(dllexport) 
                      __cdecl int sum(int a,int b);
But in such case you must inform compiler about the true, or "decorated" function name. This can be done by using the EntryPoint field of DllImport attribute:
    [DllImport("TestDll.dll", EntryPoint="sum", 
    ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
    static extern int sum(int a,int b);

It sounds very simple, becouse "int" is an isomorphic type, which means an int in C# and an int C++ are identical. What do you do when you want to operate on non-isomorhic types, such as String? Recall, that .NET string is a Class, while a C++ string is a char*, wchar_t*, or BSTR. String may be embedded in a structure, or pointed by pointer, or even something more exotic. Let's call some string function.

[DllImport("Advapi32.dll", 
                 EntryPoint="GetUserName", 
                 ExactSpelling=false, 
                 SetLastError=true)]
    static extern bool GetUserName(
      [MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer,
      [MarshalAs(UnmanagedType.LPArray)] Int32[] nSize );

This function receives two parameters: char* and int*. Because you must allocate char* buffer and receive a string by pointer, you can't use the UnmanagedType.LPStr attribute. So, you pass the ANSI string as a byte array. An int* is simpler--it's 1-element Int32 array. Let's call it:

    private void button2_Click(object sender, 
                                    System.EventArgs e)
    {
      byte[] str=new byte[20];
      Int32[] len=new Int32[1];
      len[0]=20;
      GetUserName(str,len);      
      MessageBox.Show(System.Text.Encoding.ASCII.GetString(str));
    }

This allocates 20 bytes for receiving the ANSI string, one element in Int32 array, set 20 as max string length and call it. For receiving the string from the byte array I used Text.Encoding.ASCII class.

That's enough for the first part. The second part will speak about more complex interop.

Downloads

None



Comments

  • lisseur ghd Travel Collection de minuit GHD

    Posted by lgqnwc555 on 07/16/2013 07:56am

    et est parfait pour le curling, le rouissage ou vagues. Bien sûr, il a toutes les grandes funksjonene dans GHD Classique Or comme un funksjonen auto-sommeil, les universités vendent spenning pour bruk sur Reiser, et un long câble d'alimentation supplémentaire pour les simples litt glamour use.Add à coiffer routine avec la collection métallique ghd. [url=http://ghdpascherferfr.webgarden.com/]ghd pas cher[/url] Le Param cadeau ordonné a le ghd mouette V Classic styler dans une finition riche rubis métallique. Le lisse, noir, avrundede Plater, avec un SNEV av étincelle est conçu pour y g dans un brillant, finition brillante Høy à votre style, que vous avez raison, boucle ou wave.With il est Svart, Glatt et profilert céramique Plater (avec un ! supplémentaire spesiell étincelant overflate) donne styler un blanc, finition brillante Høy à votre style.The ghd styler Metallic Collection est livré avec un élégant Svart vattert sak qui empêchent les dommages et garder les fils ryddig lorsque vous Reiser ainsi que luxueux emballage coordonnée - d'où l'Une IG cadeau parfait pour Noël. [url=http://ghdpascherfer.hpage.com/]ghd pas cher lisseur[/url] Le ressort de la boutique, il est beaucoup Cheap GHD Norge.Our lisseur ghd pas seulement pas cher mais la qualité est Veldig soutien-gorge, est la meilleure product.These ghd pas cher du monde a Flot différent versjoner av ghd stylers cheveux y hjelpe skjønnhet bevisst en y Öppna son Utseende de rêve . Ils sont conçus pour y do coiffure oppleve un grand, avec des résultats étonnants merkbart. Nous consacrons-nous ici å servir chaque client avec lisseur ghd produit beste et Best service.and ces ghd droit Rod Price mer tiltrekke you.We pense que vous nageoire vos lisseur ghd pas cher de favoris.

    Reply
  • GHD-produktene er egnet for Ã¥ fÃ¥ bare om noen form for perfekt hÃ¥r stil

    Posted by pletcherwob on 06/14/2013 11:17am

    [url=http://www.rettetangnewsnorge.com/]ghd rettetang pris[/url] Selvfølgelig platene føler meg veldig glatt og varme opp veldig raskt. Dette blir varm veldig fort! Du må være sikker på å bruke varmen matte å plassere den på benkeplater. Men betyr det også at det retter ut noen fikser i håret mitt lynraske. Jeg vil tro at hvis du hadde bølgete / krøllete hår, med måten dette varmer opp det ville gjøre styling ganske enkelt. Hvilemodus er en av de kritiske funksjonene som jeg ser etter i en styling verktøy. Det faktum at Peacock har dette er veldig viktig for meg. Den siste flatt jern som jeg kjøpte, kjøpte jeg for denne svært funksjon fordi jeg alltid paranoid at jeg kommer til å glemme å slå av min flatt jern hvis jeg forlater huset i en hast. [url=http://ghdrettetangtilbud.webgarden.com/]ghd rettetang norge[/url] Tredje, De tilbyr også avrundet fat som kan gjøre en mye mer allsidig GHD jern enn andre typer hår stylers i markedet. Hvis du liker å endre ditt hår er ofte en klar fordel at du bruker ghd hår straighteners kan også skape bølger, hopp og loops.Endelig, må du velge en GHD jern er konstruert for bruk i eksplosjoner eller frynser. GHD IV styler Mini er perfekt for mye kortere hår. Kombiner disse glimrende funksjonene den mest omfattende rettetang, men det er enklere å bruke på mindre biter av hair.Maybe du har vet hvilke ghd rettetang [url=http://www.rettetangnorgenews.net/]CHI rettetang[/url] GHD hår styler bruker oppvarmede, keramiske plater til både rette og krølle håret. Riktig vedlikehold vil sikre din GHD styler varer like lenge som mulig. Rengjøring styling produktrester fra styler bør være en del av vanlig vedlikehold. Det vil holde styler fungerer på sitt beste. Du kan enkelt rengjøre GHD styler uten å forårsake noen damage.Ceramic hår straighteners foretrekkes både for salongen og hjem styling.

    Reply
  • Lightweight stylish – Nike Free TR Befit in shoot up 2013 3 series

    Posted by Tufffruntee on 04/21/2013 12:30pm

    Nike Emancipated TR Trim 3 prominent features is to purchase the new plot: Nike Self-ruling 5 soles improved bending Gouge; new tractor formation making training more focused when; lighter ballast, the permeability is stronger, and more fashionable shoe designs not just aim for shoes [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache[/url] more smug wearing, barefoot training feel, but also more in fashion appearance. Nike Relieve TR Robust 3 provides excellent lateral perseverance, you can have the legs in the leg during training. Acrid vamp nobles breathable grating, drop suds's unique delineate can be [url=http://markwarren.org.uk/goodbuy.cfm]nike free uk[/url] seen through it. Lightweight, rugged, reduce froth facts familiar through completely some seams, more obedient, help is stronger. Requirement more advance, role of a training irritate, froth close in more parts of the shortage in return give, effervescence loose. Use twice patois moisture wicking mock materials, vapid on your feet, help maintain feet tiring and comfortable. Phylite [url=http://markwarren.org.uk/goodbuy.cfm]nike free uk[/url] midsole offers lightweight stupor unceasing, famous durability and stable outsole can do to greatly adjust the all-embracing avoirdupois of the shoe. Qianzhang pods on the outsole and heel-shaped Unripened rubber enhances the shoe multi-directional gripping power on different surfaces.

    Reply
  • http://www.tomsoutletw.com/ pwkqtx

    Posted by http://www.tomsoutletw.com/ Suttonfpw on 03/30/2013 08:08am

    ray ban caravan not that kind of put their life joke, life is precious ah! Other things to take with so oakley sunglasses outlet hell!oakley sunglasses cheap, And the in Xiaofeng Gang, the team commanded finished soon, Jack with his old players come to his new, and was accompanied by Cachia, they talked to seems in talking.ray ban sunglasses, A scene like this, Xiao Feng frowned, and then they walked toward the direction of the Mulan.ray ban sunglasses sale, Tudun, the soil array of wall. Xiao Feng's words fall the Rogge camp Mulan next began to rise in the eyes of the crowd surprised a wall blocking the thick walls and Mulan rose flush before they stopped. Originally civilians to help the marble construction of the wall to see this scenario have stopped hand, amazed again and again from time to time, even if it is used to see before the transfer uncanny ability but have never seen so dramatically, so say met miracles.

    Reply
  • Usual content of your blue carrier are business materials.

    Posted by pletcherash on 02/21/2013 12:01pm

    Personal belongings needs to be organized and are also wastes [url=http://www.sacburberryecharpe.co/burberry-femmes-tote-c-45.html]burberry homme [/url]. In classifying any waste, [url=http://www.sacburberryecharpe.co/]burberry echarpe[/url]www.sacburberryecharpe.co are disposing then recommended to their proper place- the proper place where they should be. How on earth do you do the item? Color program code your crap [url=http://www.bolsos-carolina-herrera.org/bolsos-carolina-herrera-de-hombro-c-45.html]Carolina Herrera mujer[/url]www.bolsos-carolina-herrera.org! When trash is merely placed from a plastic tote, regardless of the classification, unpleasant odour might emanate through the plastic garbage container [url=http://www.achetersacslongchamp.com/longchamps-pliage-moyen-c-4.html]sac longchamp 2013[/url]www.achetersacslongchamp.com 2013.

    Reply
  • Passing ptr and structure

    Posted by Legacy on 08/19/2003 12:00am

    Originally posted by: chhabi

    how to pass pointers and structure to the C++ dll from c#

    Reply
  • Can Unmanaged class from an DLL be exported?

    Posted by Legacy on 07/10/2003 12:00am

    Originally posted by: dnguyen

    What if i have an extension DLL created with a many exported
    classes and i want to be able to use this dll in my c# application. Is it possible? Some hints will be appreciated?
    Thanks

    Reply
  • can we pass CString reference to an unmanaged C++ dll function ?

    Posted by Legacy on 06/18/2003 12:00am

    Originally posted by: svkr

    Hi,

    Is it possible to pass a reference of CString object to
    a native C++ dll ?

    Please clarify.

    Reply
  • How to use functions from a C++ lib

    Posted by Legacy on 01/09/2003 12:00am

    Originally posted by: OS

    This article is very nice and helpful... but what if I have lib files from VC++ 6.0. Any ideas??
    Thanks in Advance
    -OS

    • calling vc++6.0 dll in C# its generated error....

      Posted by keyur4you on 03/27/2007 05:34am

      This article is very useful.. but when i have calli my vc++6.0 dll generate under given error?? An unhandled exception of type 'System.AccessViolationException' occurred in your application exe. Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. u have any ideas to solve this error??? Thanks regareds keyur

      Reply
    Reply
  • Using a com component in a C# aplication

    Posted by Legacy on 08/29/2002 12:00am

    Originally posted by: Manoj Sharma

    Hello,

    supposing this is a com dll method on some interface(in mathcom.tlb):
    [id(1), helpstring("method Add")]
    HRESULT Add([in] int a, [in]int b, [out]int *c);

    Now I want to use it in a C# application.

    Steps are:
    1. Make Metadata by executing the folowing line on the dos prompt:

    tlbimp mathcom.tlb /out:mathcommetadata.dll

    2. create a C# console application in MS .Net and do as follows:
    using System;
    using System.Reflection ;
    using System.Resources ;
    using MATHCOMib ;

    ...Main(...)
    {
    CMath obj = new CMath();
    int a = 100, b = 200, c = 0;
    c = obj.Add(a, b);
    Console.WriteLine(a + ":" + b + ":" + c);
    }


    That is it. But it does not work and cribs saying that MATHCOMLib is an unknown namespace. Pl suggest solutions.

    Regards,

    MKS

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds