24

I have written a DLL in dev C++. The DLL's name is "DllMain.dll" and it contains two functions: HelloWorld and ShowMe. The header file looks like this:

DLLIMPORT void HelloWorld(); DLLIMPORT void ShowMe(); 

And the source file looks like this:

DLLIMPORT void HelloWorld () { MessageBox (0, "Hello World from DLL!\n", "Hi",MB_ICONINFORMATION); } DLLIMPORT void ShowMe() { MessageBox (0, "How are u?", "Hi", MB_ICONINFORMATION); } 

I compile the code into a DLL and call the two functions from C#. The C# code looks like this:

[DllImport("DllMain.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void HelloWorld(); [DllImport("DllMain.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void ShowMe(); 

When I call the function "HelloWorld" it runs well and pops up a messageBox, but when I call the function ShowMe an EntryPointNotFoundException occurs. How do I avoid this exception? Do I need to add extern "C" in the header file?

2
  • 1
    Can you please post your C++ code? Commented May 2, 2013 at 9:20
  • You should probably change the calling convention to CallingConvention.StdCall. Commented May 2, 2013 at 10:57

3 Answers 3

19

The following code in VS 2012 worked fine:

#include <Windows.h> extern "C" { __declspec(dllexport) void HelloWorld () { MessageBox (0, L"Hello World from DLL!\n", L"Hi",MB_ICONINFORMATION); } __declspec(dllexport) void ShowMe() { MessageBox (0, L"How are u?", L"Hi", MB_ICONINFORMATION); } } 

NOTE: If I remove the extern "C" I get exception.

Sign up to request clarification or add additional context in comments.

9 Comments

ok,I have change the code and the problem is solved.thanks very much.
It doesn't answer how to call C++ (i.e. mangled code) functions from C#.
@Hi-Angel I don't know what a mangled code is and how to call it from C#. If you'd like to complete my answer please post a comment or you could post your own answer.
@atoMerz I'd like to know the answer :D Well, from what I found yesterday — for I was looking for it — the only way is to find the mangled names in a dll, and write these instead of an usual ones. But of course it wouldn't be portable as a name mangling isn't standardized, and so GCC's one not compatible with Visual Studio one, and both incompatible with ICC, and etc.Probably if you want to use both the compilers, you have to try at first a function name of one compiler, catch an exception for the case was no such a function, and try a function name of a next compiler, something like this.
@atoMerz btw, that's funny to me that you were the one, who solved the question by the directive extern "C"{}, which just removes a name mangling from an object file, but you still don't know what the name mangling is :D In C++ compiler can't name a function to be in an object just like «HelloWorld», because here's could be two function of the same name that receives different argument types. «Name mangling» is the thing to solve this: it appends some symbols to the name of the function based on it's own algorithm. And this algorithms (and the resulting names) differ in a compilers.
|
8
using System; using System.Runtime.InteropServices; namespace MyNameSpace { public class MyClass { [DllImport("DllMain.dll", EntryPoint = "HelloWorld")] public static extern void HelloWorld(); [DllImport("DllMain.dll", EntryPoint = "ShowMe")] public static extern void ShowMe(); } } 

4 Comments

ok,I have change the code and the problem is solved.thanks very much.
It won't work as the "HelloWorld" in the dynamic library is mangled.
@mjb Do you actually need the "EntryPoint " or is it implicit? I have seen code that do not use it. Is that a bad thing?
@progLearner, "You can use the DllImportAttribute.EntryPoint field to specify a DLL function by name or ordinal. If the name of the function in your method definition is the same as the entry point in the DLL, you do not have to explicitly identify the function with the EntryPoint field." learn.microsoft.com/en-us/dotnet/framework/interop/…
3

things that helped:

  • The: extern "C" { function declarations here in h file } will disable C++ name encoding. so c# will find the function

  • Use __stdcall for the C declaration or CallingConvention.Cdecl in the C# declaration

  • maybe use BSTR/_bstr_t as string type and use other vb types. http://support.microsoft.com/kb/177218/EN-US

  • download "PInvoke Interop Assistant" https://clrinterop.codeplex.com/releases/view/14120 paste function declaration from .h file in the 3rd tab = c# declaration. replace with dll filename.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.