C#调用go语言生成的dll

C#调用go语言生成的dll

Cgo

https://sourceforge.net/projects/mingw-w64/files/

在这里插入图片描述

离线安装

在这里插入图片描述
解压后,配置环境变量
在这里插入图片描述

gcc -v

在这里插入图片描述

go build --buildmode=c-shared -o Test.dll
package main

import "C"
import "fmt"

func main() {
	fmt.Println(Test())
}

var _count = 99

// Test :
//
//export Test
func Test() int {
	_count++
	return _count
}


在这里插入图片描述

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp11
{

    public partial class Form1 : Form
    {

        [DllImport("Test.dll", EntryPoint = "Test")]
        extern static int Test();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int r = Test();
            MessageBox.Show(r.ToString());
        }
    }
}

在这里插入图片描述

参考文档1

<think>好的,我现在需要回答用户的问题:“调用动态链接库dll哪些语言可以”。首先,用户之前询问过.NET Core的相关信息,现在转向DLL调用,可能是在考虑跨语言或跨平台开发时的互操作性。 用户的问题比较直接,但需要确保回答全面,覆盖主要编程语言,同时可能需要简要说明每种语言调用DLL的方法。用户可能对技术细节感兴趣,比如是否需要额外工具或库,或者调用时的注意事项。 首先,动态链接库(DLL)主要是Windows的概念,所以需要明确虽然有些语言可以跨平台调用,但DLL本身是Windows特有的。不过,在非Windows系统上,类似的动态库如.so(Linux)或.dylib(macOS)也存在,但用户问题特指DLL,所以可能集中在Windows环境下的语言支持。 接下来需要列举支持调用DLL语言。常见的有C/C++、C#、VB.NET、Python、Java、PowerShell、Delphi、Rust、Go等。每种语言调用方式不同,比如C/C++直接使用头文件和链接库,C#通过P/Invoke,Python使用ctypes或cffi等。 需要注意,有些语言如Java,虽然可以通过JNI调用,但步骤较为复杂。而像Python这样的脚本语言可能需要特定模块的支持。同时,跨平台语言Go或Rust,虽然可以生成调用DLL,但主要应用场景可能还是在Windows下。 另外,需要提到不同语言调用DLL时的限制,比如函数签名匹配、数据类型转换、内存管理问题(如C#的垃圾回收与原生代码交互)等,这些是常见的问题点,用户可能在实际操作中遇到,因此有必要简要说明。 最后,可能需要给出一些实际应用场景或示例,帮助用户理解不同语言调用DLL时的选择依据。例如,系统级开发可能用C/C++,快速脚本用Python,企业应用用C#等。 需要确保回答结构清晰,分点列出,语言简洁,技术术语准确但不过于晦涩。同时,考虑到用户之前询问过.NET Core,可能在跨平台开发方面有需求,可以特别指出在.NET Core中使用DLL的情况,比如通过P/Invoke在跨平台应用中调用Windows DLL的注意事项,或者使用其他跨平台替代方案。 总结回答的结构可能分为:支持的语言列表,每种语言调用方式简介,注意事项,以及应用场景建议。这样用户可以根据自己的项目需求选择合适的语言。</think>--- ### **1. 动态链接库(DLL)简介** **动态链接库(Dynamic Link Library, DLL)** 是 Windows 系统中的共享库文件,包含可由多个程序调用的代码和数据。其核心优势是**代码复用**和**模块化开发**。调用 DLL 的关键在于**语言需支持与 C/C++ 的交互**(因 DLL 通常基于 C ABI 编译)。 --- ### **2. 支持调用 DLL 的编程语言** 以下是常见的支持调用 DLL语言及其实现方式: #### **(1) C/C++** - **原生支持**:直接通过头文件(`.h`)和 `LoadLibrary`/`GetProcAddress` 函数加载 DLL。 - **示例代码**: ```c #include <windows.h> typedef int (*AddFunc)(int, int); // 定义函数指针类型 int main() { HINSTANCE hDll = LoadLibrary("math.dll"); AddFunc add = (AddFunc)GetProcAddress(hDll, "add"); int result = add(3, 5); // 调用 DLL 中的 add 函数 FreeLibrary(hDll); return 0; } ``` #### **(2) C#** - **通过 P/Invoke(平台调用)**:使用 `DllImport` 特性声明外部函数。 - **示例代码**: ```csharp using System.Runtime.InteropServices; class Program { [DllImport("math.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int add(int a, int b); static void Main() { Console.WriteLine(add(3, 5)); // 输出 8 } } ``` #### **(3) Python** - **使用 `ctypes` 模块**:动态加载 DLL调用函数。 - **示例代码**: ```python from ctypes import CDLL, c_int dll = CDLL("math.dll") add = dll.add add.argtypes = [c_int, c_int] # 指定参数类型 add.restype = c_int # 指定返回值类型 print(add(3, 5)) # 输出 8 ``` #### **(4) Java** - **通过 JNI(Java Native Interface)**:需编写 C/C++ 胶水代码桥接 Java 和 DLL。 - **步骤**: 1. 用 `native` 关键字声明 Java 方法。 2. 生成头文件(`javac -h`)。 3. 用 C/C++ 实现头文件并编译为 DLL。 4. 在 Java 中加载 DLL(`System.loadLibrary`)。 #### **(5) PowerShell** - **使用 `Add-Type` 和 P/Invoke**:直接在脚本中调用 DLL。 - **示例**: ```powershell $code = @" using System.Runtime.InteropServices; public class MathWrapper { [DllImport("math.dll")] public static extern int add(int a, int b); } "@ Add-Type -TypeDefinition $code [MathWrapper]::add(3, 5) # 输出 8 ``` #### **(6) 其他语言** | **语言** | **实现方式** | |----------------|----------------------------------------------------------------------------| | **VB.NET** | 类似 C#,使用 `Declare` 关键字或 `DllImport`。 | | **Delphi** | 使用 `external` 关键字声明 DLL 函数。 | | **Rust** | 通过 `extern "C"` 块和 `libloading` 库加载 DLL。 | | **Go** | 使用 `syscall` 包或 `cgo` 调用 DLL(需适配 Windows)。 | | **Node.js** | 通过 `ffi-napi` 或 `node-ffi` 模块(需额外安装)。 | --- ### **3. 调用 DLL 的通用注意事项** 1. **ABI 兼容性** - 函数调用约定(如 `__cdecl`、`__stdcall`)必须一致,否则可能导致栈错误。 - 示例:C# 中需指定 `CallingConvention = CallingConvention.StdCall`。 2. **数据类型映射** - 不同语言的数据类型需正确转换(如 C# `int` 对应 C `int32_t`,Python `c_int`)。 - 复杂类型(结构体、指针)需手动处理内存布局。 3. **DLL 加载路径** - 需确保程序能找到 DLL 文件(可放置在 `PATH` 环境变量目录或应用同级目录)。 4. **32/64 位兼容性** - 调用方程序与 DLL 的架构(x86/x64)必须一致,否则会崩溃。 5. **异常处理** - DLL 内部的未捕获异常可能导致宿主程序崩溃(尤其对非 C/C++ 语言)。 --- ### **4. 跨平台替代方案** 若需在 **Linux/macOS** 调用类似功能,可使用以下替代方案: | **平台** | **动态库格式** | **调用方式** | |---------------|----------------|---------------------------------------------| | **Linux** | `.so` | 使用 `dlopen`/`dlsym`(C/C++)或 `ctypes`(Python)。 | | **macOS** | `.dylib` | 类似 Linux,需注意路径和符号导出规则。 | --- ### **5. 实际应用场景建议** - **系统级开发**:优先选择 **C/C++**(直接控制内存和性能)。 - **快速脚本工具**:使用 **Python** 或 **PowerShell**(代码简洁)。 - **企业级应用**:采用 **C#** 或 **Java**(类型安全、生态完善)。 - **跨平台需求**:结合 **Rust** 或 **Go** 生成不同平台的动态库。 --- **总结**:几乎所有主流语言均可调用 DLL,但需注意**平台限制**(Windows)和**交互细节**(ABI、数据类型)。选择语言时需权衡开发效率、性能需求和目标环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值