Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

calling C++ dll from C#

Status
Not open for further replies.

nastoski

Technical User
Oct 21, 2003
21
Dear all,
When trying to import C++ dll in C# I found a problem that can not solve. When calling dll method I get an error:
Unable to find an entry point named ‘add’ in DLL ‘cppdll.dll’

This is the example of the code:
DLL code in C++ (VS 2005)

cppdll.h
class __declspec(dllexport) Adder
{
public:
Adder(){;};
~Adder(){;};
int add(int x,int y);
};

cppdll.cpp
#include "cppdll.h"

int Adder::add(int x,int y)
{
return (x+y);
}


C# client program
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace callinglibrary
{
class Program
{
[DllImport("cppdll.dll")]
public static extern int add(int x, int y);

static void Main(string[] args)
{
int c;
c = add(5, 6);
}
}
}


Can you please help me and tell me what seems to be a problem.

Thanks in advance.

Regards

Igor Nastoski
 
'add' is a member of the class Adder and so cannot be simply referenced as 'add'; you need a class reference as a qualifier.
 
Hi
Thanks for your quick response. Could you please give me the example for my case.

Thanks
 
Here is one way. extern "C" in the cpp source is supposed to unmangle the method name, it did not for me? To get the EntryPoint for the DllImport directive you can use dumpbin /exports adder.dll. You could use an ordinal for the EntryPoint but that changes as you add methods.
Code:
// adder.h
using namespace System;
#define DLLExport __declspec(dllexport)
class Adder
{
	public:
		Adder(){;};
		~Adder(){;};
		DLLExport int add(int x,int y);

};
Code:
// adder.cpp
#include "stdafx.h"
#include "adder.h"

extern "C" int Adder::add(int x,int y)
{
	return (x+y);
}
Code:
//compile with csc CallAdder.cs /r:C:\CPPPrograms\adder\Release\adder.dll 
using System;
using System.Runtime.InteropServices;
class CallAdder
{
  [b][DllImport(@"C:\CPPPrograms\adder\Release\adder.dll", EntryPoint="?add@Adder@@QAEHHH@Z")][/b]
    public static extern int add(int x, int y);
    
    static void Main(string[] args)
    {
        int c;
        try
        {
          c = add(5, 6);
          Console.WriteLine(c);
        }
        catch(EntryPointNotFoundException epnfe) {
         Console.WriteLine(epnfe.ToString());
        }
        catch(Exception e)
        {
          Console.WriteLine(e.ToString());
        }
    }
}

Marty
 
It is not an obligation to build your DLL in a class structure
You can define it in this way.

// in the .c file
extern "C" __declspec(dllexport) int _stdcall Add(int a, in b)
{
return a+b;
}

// in the .h file
extern "C" __declspec(dllexport) int _stdcall Add(int a, int b);

Then copy your DLL in Windows/System32 and import it in this way.

[DllImport("MyDLL.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int Add(int a, int b);

StreamWriter sw = File.CreateText("Excptionfile.txt");
try
{int c=Add(5,3);
sw.WriteLine(c.ToString());
sw.Close();
}
// DLL not existing in c:\windows\System32
catch (DllNotFoundException e1)
{
sw.WriteLine(e1.ToString());
sw.Close();
}
catch (EntryPointNotFoundException ex)
//function not existing in the DLL
{ sw.WriteLine(ex.ToString());
sw.Close();
}


The advantage of defining your DLL as a class is to initialize it and release it in the beginning and the end of interaction with the DLL

Regards
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top