createdll tutorial VC++ 2005

  • Thread starter Thread starter Eran.Yasso
  • Start date Start date
E

Eran.Yasso

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,
 
"""(e-mail address removed) ÐÉÓÁÌ(Á):
"""
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,

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();
}
}
}
 
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.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
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,

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.");
}
}
}
 
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).
 
Imm said:
"""(e-mail address removed) ÐÉÓÁÌ(Á):
"""
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,

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();
}
}
}

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,
 
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,

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;
}
}
}
 
Back
Top