Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / November 2006

Tip: Looking for answers? Try searching our database.

createdll tutorial VC++ 2005

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Eran.Yasso@gmail.com - 23 Nov 2006 21:04 GMT
Hi,

I need to develop DLL that exposes API. It should be accessed by C#.
Can any one please help me with that? any tutorial or link would be
greate.

TIA,
Imm - 24 Nov 2006 04:21 GMT
"""
> Hi,
>
[quoted text clipped - 3 lines]
>
> TIA,

Create dll in Visual C++ 2005:

1. "New Project\Win32\Win32 Console Application" create a new project.
-> OK
2. "Application Settings\ Empty project" -> FINISH
3. In "Solution Explorer" on "Source files" add new item "main.cpp"
4. Copy the text:

#include <windows.h>
#include <cstring>

int __declspec(dllexport) FuncA(int i)
{
   return i*10;
};
int __declspec(dllexport) FuncB(int i)
{
   return i*100;
};
char userLogin[80], userPassword[80];
bool __declspec(dllexport) camomileLogin(char user_name[], char
user_password[])
{

    strcpy(userLogin,user_name);
    strcpy(userPassword,user_password);
   return true;
};
__declspec(dllexport) char* camomileGetUserLogin()
{
    return userLogin;
};

5. In "Property Pages\Configuration Properties\General\Configuration
Type" select "Dynamic Library (.dll)" APPLY
6. Build.

You may use the tool ""C:\Program Files\Microsoft Visual Studio
8\Common7\Tools\Bin\Depends.Exe""

Code for C# :

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

namespace camomile_root
{
   public partial class Form1 : Form
   {
       [DllImport("libcamomile.dll", EntryPoint = "?FuncA@@YAHH@Z")]
       public static extern int FuncA(int x);
       [DllImport("libcamomile.dll", EntryPoint = "?FuncB@@YAHH@Z")]
       public static extern int FuncB(int x);
       [DllImport("libcamomile.dll", EntryPoint =
"?camomileGetUserLogin@@YAPADXZ")]
       public static extern string camomileGetUserLogin();
       [DllImport("libcamomile.dll", EntryPoint =
"?camomileLogin@@YA_NQAD0@Z", CharSet = CharSet.Ansi, CallingConvention
= CallingConvention.StdCall)]
       public static extern bool camomileLogin(string user_name,
string user_password);

       public Form1()
       {
           InitializeComponent();
       }

       private void okey_Click(object sender, EventArgs e)
       {
           int answer = FuncA(57);
           userLogin.Text = answer.ToString();
           int answer1 = FuncB(57);
           userPassword.Text = answer1.ToString();
           string s = "user";
           string s2 = "passwd";
           camomileLogin(s,s2);
           string answer2 = camomileGetUserLogin();
           userPassword.Text = answer2;

       }

       private void cancelButton_Click(object sender, EventArgs e)
       {
           Close();
       }
   }
}
Bruno van Dooren [MVP VC++] - 24 Nov 2006 10:31 GMT
Not an ideal solution, because you have to import mangled names, which can
be annoying to figure out, and the mangled names change if you add a funcion
parameter.
A better method is so insure that the function names are not mangled.
The easiest ways to do this are either change

> int __declspec(dllexport) FuncA(int i)
to

extern "c"
{
__declspec(dllexport) int __cdecl FuncA(int i);
}

int FuncA(int i)
{
   //..implementation here
}
or add a DEF file to your project and declare function exports in there.
that way you can also export unmangled functions that use the stdcall
calling convention.

>        [DllImport("libcamomile.dll", EntryPoint = "?FuncA@@YAHH@Z")]
>        public static extern int FuncA(int x);

Do not foget to use the CallingConvention attribute to specify the calling
convention that was used. otherwise there will be an access violation.

Signature

Kind regards,
   Bruno van Dooren
   bruno_nos_pam_van_dooren@hotmail.com
   Remove only "_nos_pam"

Eran.Yasso@gmail.com - 24 Nov 2006 22:16 GMT
> """Eran.Yasso@gmail.com ÐÉÓÁÌ(Á):
> """
[quoted text clipped - 99 lines]
>     }
> }

Hi All and thanks for your reply,

Imm,I have question regarding your answer.

I changed the functions name in the dll. when i changed the Entry
points in C#, with the same name, I got massage that the entry points
can't be found. I changed function FuncA to GetPosition and FuncB to
SetPosition. I also changed in C#:
       [DllImport("Yasso.dll", EntryPoint = "?FuncA@@YAHH@Z")]
       public static extern int FuncA(int x);
to
       [DllImport("Yasso.dll", EntryPoint = "?GetPosition@@YAHH@Z")]
       public static extern int GetPosition(int x);

Why is it not working?
TIA,
Imm - 27 Nov 2006 04:00 GMT
> Hi All and thanks for your reply,
>
[quoted text clipped - 12 lines]
> Why is it not working?
> TIA,

I have not problem. You mayby don't  rewrite your new version dll and
you C# see old version.

See my source code. You passible found your misteke. I changed FuncA to
GetPosition and rewrite dll to folder with C# executable file. This is
All.

See other answers. its very good.

#include <windows.h>
#include <cstring>
int __declspec(dllexport) GetPosition(int i) // it was change
{     return i*10; };
int __declspec(dllexport) FuncB(int i)
{ return i*100; };
char userLogin[80], userPassword[80];
bool __declspec(dllexport) camomileLogin(char user_name[], char
user_password[])
{    strcpy(userLogin,user_name);
    strcpy(userPassword,user_password);
   return true;
};
__declspec(dllexport) char* camomileGetUserLogin()
{
    return userLogin;
};

C# :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace testdllCSharp
{    public partial class Form1 : Form
   {   [DllImport("testdll.dll", EntryPoint = "?GetPosition@@YAHH@Z")]

       public static extern int GetPosition(int x);// <---  it was
change  ^
       [DllImport("testdll.dll", EntryPoint = "?FuncB@@YAHH@Z")]
       public static extern int FuncB(int x);
       [DllImport("testdll.dll", EntryPoint =
"?camomileGetUserLogin@@YAPADXZ")]
       public static extern string camomileGetUserLogin();
       [DllImport("testdll.dll", EntryPoint =
"?camomileLogin@@YA_NQAD0@Z", CharSet = CharSet.Ansi, CallingConvention
= CallingConvention.StdCall)]
       public static extern bool camomileLogin(string user_name,
string user_password);
       public Form1()
       { InitializeComponent(); }
       private void button1_Click(object sender, EventArgs e)
       {   int answer = GetPosition(57);// it was change
           userLogin.Text = answer.ToString();
           int answer1 = FuncB(57);
           userPassword.Text = answer1.ToString();
           string s = "user";
           string s2 = "passwd";
           camomileLogin(s, s2);
           string answer2 = camomileGetUserLogin();
           userPassword.Text = answer2;
       }
   }
}
Rich - 24 Nov 2006 14:40 GMT
> Hi,
>
[quoted text clipped - 3 lines]
>
> TIA,

Here is a link to a good tutorial on setting up a project to build an
unmanaged DLL:
    http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855/

I followed this article and created a very simple test DLL (using a
.DEF file for exporting functions).

Here is the C++ file:

#include <iostream>
#include "Test_DLL.h"

#ifdef __cplusplus
extern "C" {
#endif

   int Add(int a, int b) {
       return( a + b );
   }

   void Function( void ) {
       std::cout << "DLL Called!" << std::endl;
   }

#ifdef __cplusplus
}
#endif

Here is the Header file:

#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#include <iostream>

#ifdef __cplusplus
extern "C" {
#endif

   int Add(int a, int b);
   void Function( void );

#ifdef __cplusplus
}
#endif

#endif

Here is the DEF file:

LIBRARY Test_DLL
EXPORTS
  Add        @1
  Function        @2

Once you have your unmanaged DLL, test it from an unmanaged application
to make sure everything works.
This builds to a .DLL file and a .LIB file.  We need these two files
plus the header file for an application to use the DLL.
Here is a simple test program that tests our DLL:
#include <iostream>
#include "Test_DLL.h"

int main()
{
  Function();
  std::cout << Add(32, 58) << "\n";
  return(1);
}

Now you need to build a MANAGED DLL (assembly) so you can call your
functions from C# (or VB or any other .NET language).
Here is the managed C++ file for the managed DLL:

using namespace System::Runtime::InteropServices;

[DllImport("Test_DLL", EntryPoint="Add")]
extern "C" int Add(int a, int b);

[DllImport("Test_DLL", EntryPoint="Function")]
extern "C" void Function( void );

namespace Test_DLL_CLR {

    public ref class Test_DLL_Class {
    public:
        // Function: Add
        int Add_clr(int a, int b)
        {
            return( Add( a, b) );
        }

        // Function: Function
        void Function_clr(void)
        {
            Function();
        }
    };
}

Once you have your managed DLL, you can include it in your C# project
as a reference.  You should now be able to use the namespace defined in
the managed DLL (along with everything defined in that namespace).
Here is C# code that uses the managed DLL:

using System;
using System.Collections.Generic;
using System.Text;
using Test_DLL_CLR;

namespace Test_DLL_CLR_app_cs
{
   class Program
   {
       static void Main(string[] args)
       {
           Test_DLL_Class myclass = new Test_DLL_Class();
           int val;

           Console.WriteLine("C# Test_DLL_CLR Test Program");

           myclass.Function_clr();
           val = myclass.Add_clr(123, 456);

           Console.WriteLine("val = " + val);

           Console.WriteLine("Finished.");
       }
   }
}
Ben Voigt - 24 Nov 2006 15:38 GMT
> Hi,
>
> I need to develop DLL that exposes API. It should be accessed by C#.

Does it need to be used from any non-.NET language?

> Can any one please help me with that? any tutorial or link would be
> greate.

building a C++/CLI assembly for consumption by C# is trivially easy, just do
new project -> C++ -> CLR -> Class Library, then add some "ref class"
definitions (there's a wizard for that too, right click the C++ project and
do Add -> New Class).

> TIA,

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.