从 C# 程序访问 DLL 中的方法

Posted

技术标签:

【中文标题】从 C# 程序访问 DLL 中的方法【英文标题】:Access a method from a DLL from C# program 【发布时间】:2011-06-17 22:16:36 【问题描述】:

我有一个 C 程序并创建了一个 DLL 文件。我正在使用 Windows Vista 和 Visual C++。

现在我需要从 C# 代码的 Main() 方法访问该 DLL 中的方法。这样做的步骤是什么?

到目前为止,我已经添加了 DLL 文件作为参考,之后我该怎么办?

这只是一个例子:

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

请注意,这个类也使我们能够使用其他 .lib 函数,但我能够成功地从中创建一个 DLL。 (我不知道这是否相关)

现在我需要从我的 C# Main() 访问这个方法;

[STAThread]
static void Main()

  // I need to call that main1() method here

  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new Form1());

【问题讨论】:

无法添加对本机 C DLL 的引用。显然,您没有使用真正的 C dll,也许是 C++/CLI 的。在这种情况下不需要什么特别的,您公开的“ref class”声明可以直接在 C# 程序中使用。 是的,它是一个 C++/CLI 项目。根据您的回答,它似乎可以直接完成,通过说'ref class'是指我的 C 类吗?以及如何公开?到目前为止我所做的步骤是,添加 dll 作为参考,并添加以下语句using detect.h,并尝试从 C#、Main() 方法访问它,例如; detect.the_method_i_need() ,但它没有那样工作。帮助 【参考方案1】:

请参阅using a class defined in a c++ dll in c# code,它有一个很好的接受答案。正如 Hans Passant 在 cmets 中所写,您不能将本机 DLL 添加为对 C# 项目的引用。

当我引用自己的一个本地 DLL 时,我通常要么在 C# 项目和生成本地 DLL 的项目之间添加依赖关系,要么将 DLL 作为链接内容文件添加到 C# 项目中,就像这样:

    右键单击项目并选择“添加”>“现有项目”。 浏览并选择所需的 DLL,但不要单击添加。 点击添加按钮右侧的小箭头并选择添加为链接。 选择现在出现在 C# 项目中的 DLL 并转到其属性。 确保您已将 Build Action 设置为 Content

这会将 DLL 复制到 C# 项目的 bin\Debug 文件夹,并确保如果您决定创建安装项目,您可以轻松引用所有内容文件并包含它们在 Microsoft 安装程序包中。

现在,为了能够查看在您的本地 DLL 中编写的函数,您必须注意导出它们(参见 Exporting C Functions for Use in C or C++ Language Executables 和 Exporting from a DLL Using __declspec(dllexport))。所以你必须在你的函数声明周围添加一个extern "C" 块(我假设你在 .cpp 源文件中编写了你的​​代码,这意味着编译器将发出 mangled 函数名称,如果你没有将它们声明为 extern "C"):

extern "C"

    __declspec (dllexport) void __cdecl Foo(const char* arg1);


...

void Foo(const char* arg1)

    printf ("Hello %s !", arg1);

__declspec (dllexport) 装饰意味着编译器/链接器必须使函数从 DLL 外部可见。 __cdecl 定义了如何将参数传递给函数(执行此操作的标准“C”方式)。

在您的 C# 代码中,您必须引用 DLL 的导出方法:

class Program

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

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

您应该阅读Platform Invoke Tutorial,它提供了所有血淋淋的细节。

【讨论】:

您好@Pierre,我按照您的步骤操作,但是当我编译时,我不确定如何将 Content 设置为 Build Action代码,我没有在我的 C# 项目的 bin\Debug 中找到我的 DLL 的副本。希望你能在这里帮助我,你能告诉我如何访问我从我的 C# 项目的 Main() 方法中添加的那个 DLL 的方法。 @illep:点击C#项目中的DLL文件,按F4。在“属性”工具窗口中,第一行标记为“构建操作”。单击它的右侧,选择“内容”。确保将“复制到输出目录”设置为复制选项之一。 @illep:编辑您的帖子并添加您想要访问的 C 代码示例。您必须确保使用 DLL 导出指令正确修饰您的 C 函数。 我用示例代码编辑了我的帖子,请帮助我。干杯!【参考方案2】:

您正在寻找Platform Invoke 和[DllImport] 属性。

【讨论】:

我做了以下 /n ` [DllImport("detect.dll")] internal static extern int main1();` ,detect.dll 是我创建的 DLL 的名称。 main1() 是我希望从我的 C# 代码中执行的方法。现在,从我的 C# 代码中,我调用了 main1();方法,我得到一个错误 DLL not found exception,但 DLL 在 bin\Debug 文件夹中。我该如何解决这个问题。注意:这就是我添加 DLL 的方式,R-Click 项目并添加引用 --> 选择 DLL【参考方案3】:

您需要阅读 P/Invoke aka pinvoke aka "Platform Invoke":

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

【讨论】:

是的,我已经阅读了几个关于此的教程,但我不明白 public static extern 是什么意思。我无法编辑使用 Visual C++ 编写的 C 代码。无论如何,我将代码作为 DLL 文件。例如考虑以下代码段; void main() printf("HELLO WORLD"); 以上是我的 C 代码,现在它是一个 DLL,我如何从我的 C# Main() 方法访问这个 main()。我基本上想执行 main() (我的 c 代码)中的内容。救命! @illep:如果你不能修改你的 DLL,那么你就不走运了——必须导出函数才能从外部世界访问它们。如果您的 DLL 是伪装的 EXE(具有工作的 main 函数),您可以使用 System.Diagnostics.Process.Start 执行该 DLL,我猜。 @Pierre 是的,我已经尝试过了,但我不想打开控制台。有没有办法避免这种情况? @illep:是的,您可以在隐藏模式下启动控制台应用程序(使用ProcessStartInfo 并指定WindowStyle = ProcessWindowStyle.Hidden)。

以上是关于从 C# 程序访问 DLL 中的方法的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 中的外部 DLL 访问 windows 窗体控件

MFC dll 中的访问冲突(用 C++/CLI 包装)从 C# 程序开始

从c#访问c++ dll库[重复]

如何在C#中实现OPC数据访问

从 C++ 调用 C DLL 会导致访问冲突,但 C# 项目与 DllImport 工作

从 c# 访问 C++ .lib 库