为什么我不能在C#中使用P/Invoke调用C DLL中的函数?

u5rb5r59  于 2023-02-21  发布在  C#
关注(0)|答案(1)|浏览(156)

获取错误:

丙:

#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;
             }
             
         }
     }

这个想法是学习如何在c#中使用c中的函数。
此外,我想使用open62541库的OPC UA服务器,使用户界面与Windows窗体。

dw1jzc5e

dw1jzc5e1#

您需要将DLL中的函数标记为导出。有两种方法。您可以创建一个.def文件并命名导出的函数,或者将说明符__declspec(dllexport)添加到函数签名中。
要创建.def文件,请在Visual Studio中打开C DLL项目,右键单击“源文件”,然后在“Visual C++”-〉“代码”下,选择“模块定义文件(.def)"。在新创建的.def文件中,您可以列出希望导出的函数,如下所示:

LIBRARY mydll
EXPORTS
    function1
    function2
    function3

然后,在生成DLL时,function1function2function3都可用。
此外,请记住,除非您手动指定调用约定(例如int __stdcall function1(int a, int b);),否则调用约定默认为__cdecl,因此当您添加行以通过P/Invoke导入函数时,还必须具有属性CallingConvention = CallingConvention.CDecl。如果不匹配调用约定,将导致调用代码中的堆栈损坏。

相关问题