Klasik
Klasik

Reputation: 892

Why am I unable to call a function in a C DLL using P/Invoke in C#?

Getting an error:

enter image description here

C:

#include <stdio.h>

const char *print(const char *message)
{
    if (message != 0) {
        const char *message1 = "Connected";
        return message1;
        message = "";
    }
    return "Message empty";
}

C#:

     public partial class Form1 : Form
     {
         /*Declaration*/
         bool T;
         string a;
         
         [DllImport("DLLC.dll")]
         static extern string print(string message);
 
         public Form1()
         {
             InitializeComponent();
         }
                 
         private void button1_Click(object sender, EventArgs e)
         {
             a = print("Send");
             if (T)
             {
                 label1.Text = a ;
                 T=false;
             }
             else{
                 label1.Text = "BAD";
                 T=true;
             }
             
         }
     }

The idea is learn how to use functions from c in c#.

Also I would like use open62541 library for OPC UA SERVER and make UI with windows forms.

Upvotes: 2

Views: 452

Answers (1)

Govind Parmar
Govind Parmar

Reputation: 21542

You need to mark the function in the DLL as exported. There are two ways of doing this. You may either create a .def file and name the exported functions, or add the specifier __declspec(dllexport) to the function signature.

To create a .def file, in Visual Studio with the C DLL project open, right click on "Source Files" and then under "Visual C++" -> "Code", select "Module-Definition File (.def)". In the newly created .def file, you can list the functions you wish to export, like so:

LIBRARY mydll
EXPORTS
    function1
    function2
    function3

Then, when you build the DLL, function1, function2, and function3 are available.

Also, keep in mind that unless you manually specify a calling convention (e.g. int __stdcall function1(int a, int b);), the calling convention is __cdecl by default, and so when you add the line to import the function through P/Invoke, you must also have the attribute CallingConvention = CallingConvention.CDecl. Failing to match calling conventions will cause stack corruption in the calling code.

Upvotes: 4

Related Questions