c# - 从 Visual Studio 中的 C# 代码传递到 C 代码

标签 c# c visual-studio dll dllimport

我对如何从我的 C# 代码引用我的 C 代码感到困惑。我已经阅读并意识到 DLL 很有用,但我不明白如何连接我的 dll。根据我的理解,我从我的c代码中生成了dll?请帮忙

C#( Visual Studio Code )

public partial class Form1: Form{
  [DllImport("simple.dll", CallingConvention = CallingConvention.Cdec1)]
  public static extern void pinfo(string str);

  private void button1_Click(object sender, EventArgs e){
      pinfo("yay");
  }
}

C 代码 - simple.c

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
__declspec( dllexport ) void pinfo(char* str){
    printf("You are in the method %s\n, str);
}

int main(void){
}

我的问题是如何将 C 代码连接到 C# 代码,以便打印出“You are in the method yay”这一行?我不明白如何将 dll 文件链接到 Visual Studio 或如何创建 dll 文件。谢谢

最佳答案

让 P/Invoke (DllImport) 在 .NET 中工作有 3 个主要步骤:

  1. 从 C/C++ 项目中导出函数。

    在 Visual C++ 中,使用 __declspec( dllexport )extern "C" 修饰符分别告诉编译器导出 DLL 中的函数,因此通过名称可见,并且不要破坏名称 - 否则,如果项目内没有调用者,编译器将完全删除该函数(“死代码删除”)。函数也可以通过序数来导出,这可能不是您感兴趣的。

  2. 确保您正在针对相同的 ISA 进行构建。

    当您在 .NET 中使用 P/Invoke 时,您引用的 DLL 将被加载到托管 .NET 进程中,因此该 DLL 必须构建为与当前 .NET 进程相同的 CPU 指令集。默认情况下,.NET 项目在 AnyCPU 模式下运行,但在 Visual Studio 的最新版本中,它们“更喜欢”32 位 (x86) 模式而不是 64 位 (x64/AMD64)。为了防止任何混淆,请决定您需要 32 位还是 64 位模式,并强制您的 .NET 项目仅针对该 ISA 构建,然后将您的 C/C++ 项目设置为也针对该 ISA 构建。

  3. 确保目标 DLL 文件位于 .NET 可执行文件的 PATH 中 - 通常这意味着只需将其放置在与构建的.NET可执行文件。

    请注意,由于此 DLL 文件不是 .NET 程序集,因此没有“项目引用”或“程序集引用”的概念,因此您需要专门配置项目,以便 Visual Studio (MSBuild) 复制 DLL将文件添加到 bin 文件夹 - 您可以通过将 DLL 文件添加到解决方案资源管理器中的 .NET 项目根目录,然后选择该文件并打开“属性”窗口并选择“生成操作:内容”来执行此操作。和“复制到输出目录:始终”。

关于“链接” - DLL 在编译时不会链接 - 线索就在名称中:“动态链接”:链接是在运行时由操作系统执行的,而不是由操作系统执行的编译器。

有关 P/Invoke 的更多信息,我建议阅读此 QA:Why are Cdecl calls often mismatched in the "standard" P/Invoke Convention?

关于c# - 从 Visual Studio 中的 C# 代码传递到 C 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44271340/

相关文章:

c# - 一路异步?

C# - 动态参数是否装箱

c# - WCF 客户端代理初始化

c - int 是 4 个字节,但仍然可以存储在 char 中,为什么没有溢出

c - Makefile递归不传递CPPFLAGS

git - 如何修复 git 损坏的索引而不丢失 git 历史记录?

c# - 如何通过 Tag 获取 ComboboxItem 索引?

c - 如何使用 Visual Studio 2010 进行 C 开发?

c# - 在 UWP 中使用滑动手势

c# - 将我填充的数组值显示到列表框中并可选择删除它们