6

I have a C program and i have created a DLL file. I am using Windows Vista, and Visual C++.

Now I need to access a method from that DLL, from the Main() method of a C# code. What are steps of doing so?

So far I have added the DLL file as reference, thereafter what should I do?

This is only an example:

int main1( void ) {
  prinf("Hello World");
}

Please note that this class also makes us of other .lib functions, but i was able to successfully create a DLL out of it. (I don't know if this is relevant)

Now i need to access this method from my C# Main();

[STAThread]
static void Main()
{
  // I need to call that main1() method here

  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new Form1());
}
user2864740
  • 60,010
  • 15
  • 145
  • 220
illep
  • 185
  • 2
  • 6
  • 13
  • Adding a reference to a native C DLL is not possible. Clearly you are not using a real C dll, maybe a C++/CLI one. Nothing special is needed in that case, the "ref class" declarations you made public are directly available in a C# program. – Hans Passant Jun 17 '11 at 23:33
  • Yes, it is a C++/CLI project. Based on your answer it seems it could be directly done, by saying 'ref class' do you mean my C class ? and how do i make it public ? The steps i did so far are, added the dll As a reference, and added the following statement `using detect.h`, and tried to access it from the C#, Main() method like ; `detect.the_method_i_need()` , but it didn't work like that. HELP – illep Jun 18 '11 at 08:23

3 Answers3

8

See using a class defined in a c++ dll in c# code which has a great accepted answer. And as Hans Passant wrote in the comments, you cannot add a native DLL as a reference to a C# project.

When I refer to one of my own native DLLs, I usually either add a dependency between the C# project and the project which generates the native DLL, or I add the DLL as a linked content file in the C# project, like so:

  1. Right-click on the project and choose Add > Existing Item.
  2. Browse and select the DLL you want, but don't click Add yet.
  3. Click on the tiny arrow at the right of the Add button and select Add As Link.
  4. Select the DLL that now appears in your C# project and go to its properties.
  5. Make sure you have Build Action set to Content.

This will copy the DLL to the bin\Debug folder of the C# project and make sure that, if you once decide to create a Setup project, you can easily reference all content files and include them in the Microsoft Installer package.

Now, to be able to see the functions written in your native DLL, you have to take care of exporting them (see Exporting C Functions for Use in C or C++ Language Executables and Exporting from a DLL Using __declspec(dllexport)). So you'd have to add an extern "C" block around your function declaration (I am assuming you wrote your code in a .cpp source file and this means that the compiler will emit mangled function names if you do not declare them as being extern "C"):

extern "C"
{
    __declspec (dllexport) void __cdecl Foo(const char* arg1);
}

...

void Foo(const char* arg1)
{
    printf ("Hello %s !", arg1);
}

The __declspec (dllexport) decoration means that the compiler/linker will have to make the function visible from outside of the DLL. And the __cdecl defines how parameters will be passed to the function (the standard "C" way of doing this).

In your C# code, you'll have to refer to your DLL's exported methods:

class Program
{
    [DllImport("mydll.dll")]
    internal static extern void Foo(string arg1);

    static void Main()
    {
        Program.Foo ("Pierre");
    }
}

You should read the Platform Invoke Tutorial which gives all the gory details.

Community
  • 1
  • 1
Pierre Arnaud
  • 10,212
  • 11
  • 77
  • 108
  • Hello @Pierre, I followed your steps, and i am not sure how to set **Content** as **Build Action**, however, when i compiled the code, i didn't find a copy of my DLL in the _bin\Debug_ of my C# project. Hope you could help me here, and could you also tell me how to access a method of that DLL that i added from the Main() method of my C# project. – illep Jun 18 '11 at 08:00
  • 1
    @illep: Click on the DLL file in the C# project, press F4. In the Properties tool window, the first line is labeled "Build Action". Click on the right of it, select "Content". Make sure that "Copy to Output Directory" is set to one of the copy options. – Pierre Arnaud Jun 18 '11 at 08:27
  • @illep: Edit your post and add a sample of your C code you want to have access to. You must make sure that your C function is properly decorated with a DLL export directive. – Pierre Arnaud Jun 18 '11 at 08:28
  • I have edited my post with a sample code, Please help me out. cheers ! – illep Jun 18 '11 at 08:44
0

You're looking for Platform Invoke and the [DllImport] attribute.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • I did the following /n ` [DllImport("detect.dll")] internal static extern int main1();` , `detect.dll` is the name of my DLL that i created. main1() is the method i am looking to execute from my C# code. Now, from my C# code i called the main1(); method and i get an error **DLL not found exception**, but the DLL is in the _bin\Debug_ folder. How do i resolve this. note: This is how i added my DLL, R-Click on the project and add Reference --> select DLL – illep Jun 18 '11 at 08:17
0

You need to read up on P/Invoke aka pinvoke aka "Platform Invoke":

http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • Yes, i have gone through several tutorials on this, but i don't understand what **public static extern** means. i am unable to edit my C code which has been written using visual C++. anyway i have the code as a DLL file. for example consider the following code segment; `void main(){ printf("HELLO WORLD"); }` the above is my C code, and its now a DLL, how do i access this main() from my C# Main() method. i basically want to execute what is in that main() (of my c code). Help ! – illep Jun 18 '11 at 08:06
  • @illep: if you cannot modify your DLL, then you are out of luck -- functions must be exported so that they can be accessed from the outside world. If your DLL is an EXE in disguise (with a working `main` function), you could just execute that DLL using `System.Diagnostics.Process.Start`, I guess. – Pierre Arnaud Jun 18 '11 at 12:47
  • @Pierre Yes, i have tried that, but i don't want the Console to open. Is there anyway to avoid this ? – illep Jun 18 '11 at 16:41
  • @illep: Yes, you can start a console application in hidden mode (use `ProcessStartInfo` and specify `WindowStyle = ProcessWindowStyle.Hidden`). – Pierre Arnaud Jun 18 '11 at 20:11