C#调用 C DLL Golang DLL

本文介绍了如何使用C#调用编译自Go语言的DLL,特别关注通过指针传递参数和解决跨平台适配问题,包括字符类型转换与CallingConvention设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GoLang定义导出方法

通过指针传入函数方法参数

import "C"

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

//export PrintHello2
func PrintHello2(Input *C.char, Output **C.char) int32 {
    *Output = C.CString(fmt.Sprintf("From DLL: Hello, %s!
", C.GoString(Input)))
    return int32(len(C.GoString(*Output)))
}
 
//export PrintHello4
func PrintHello4(Input *C.char) *C.char{
    return C.CString(fmt.Sprintf("From DLL: Hello, %s!
", C.GoString(Input)))
}

一定要加 “import “C”” 否则方法不能导出

编译成 DLL

#动态库
go build -buildmode=c-shared -o libmain32.dll main.go
//.dll 和 .so 名字而已,习惯而已
go build -buildmode=c-shared -o libmain32.so main.go
#静态库
go build -buildmode=c-archive -o libmain32.a main.go

c#调用DLL

class Program
{
    [DllImport("goDLL.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
    public static extern int PrintHello2([In] byte[] data, ref IntPtr output);
 
    [DllImport("goDLL.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
    public static extern IntPtr PrintHello4(byte[] data);
 
    static void Main(string[] args)
    {
        string res = "demo";
        IntPtr output= IntPtr.Zero;
        var a = PrintHello4(Encoding.UTF8.GetBytes(res));
 
        Console.WriteLine("PrintHello4 Returns: " + Marshal.PtrToStringAnsi(a));
        var i = PrintHello2(Encoding.UTF8.GetBytes(res), ref output);
 
        Console.WriteLine("PrintHello2 Returns: " + i);
        Console.WriteLine("Ref Val changed to: " + Marshal.PtrToStringAnsi(output, i));
    }
}

通过指针将数据输出

C#适配 Any CPU

实现的基本思路为(x64和x86环境都装上,编译两种dll,根据运行环境选择dll)
分别导入x64和x86的函数 ,并添加后缀
判断当前进程是x64还是x86
呼叫与对应的函数

[DllImport("testdll32.dll", EntryPoint="add")
private static extern int add86(int a, intb);

[DllImport("testdll64.dll", EntryPoint="add")
private static extern int add64(int a, intb);
public static int add(int a, int b)
{
    if (Environment.Is64BitProcess)
        return add64(a,b);
    return add86(a,b);
}

x64运行挺好,但是在x86运行出现异常: 调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配

出现这个错误,可能
1.参数类型不匹配
难道char*不能用string来表示,IntPtr是一定可以的.将C++类型更改成int类型后测试,发现仍然出错,这样看来,不可能是参数类型不匹配了
2. 调用约定不匹配
DllImport还有一个CallingConvention的属性,默认值是CallingCovention.Stdcall, 此处更改成Cdecl(c/c++默认调用方式)就可以了

[DllImport("datalib.dll", EntryPoint = "test",CallingConvention=CallingConvention.Cdecl)]  
public static extern void test(string str); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值