我对如何从我的 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 个主要步骤:
从 C/C++ 项目中导出函数。
在 Visual C++ 中,使用
__declspec( dllexport )
和extern "C"
修饰符分别告诉编译器导出 DLL 中的函数,因此通过名称可见,并且不要破坏名称 - 否则,如果项目内没有调用者,编译器将完全删除该函数(“死代码删除”)。函数也可以通过序数来导出,这可能不是您感兴趣的。确保您正在针对相同的 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 构建。
确保目标 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/