golang调用C语言dll遇到的坑

背景需求

需要使用golang在windows下调用调用一个exe程序。

刚开始使用exec去启动,但如果用exec启动exe程序时如果遇到一些错误,例如缺少dll,则exec的错误需要自己进行处理后在展示给用户看。

所以直接使用windowsApi调用exe程序。

系统位数导致的dll导出方法名和所想不同

在使用golang调用C函数时可以使用FindProc

我的dll函数名为 foobar(int)

例如

proc, err := dll.FindProc("foobar")

因为有一些用户是32位系统,会提示找不到dll的函数。

把32位和64位的dll扔到depends发现,导出的函数名和自己所定义的不同。

32位:

_foobar@4

64位:

foobar

那么在64位系统下使用是正常的,但换到32位就会出现上边说的找不到foobar这个函数,它被修饰了。

_foobar@4的下划线的意思目前不清楚,后边的@4意思是参数字节

问了GPT:
问:为什么32位的dll为:_foobar@4 ,而64位是foobar
答:这是因为在 Windows 平台上,32位和64位的 DLL 根据不同的调用约定会使用不同的名称修饰规则。32位 DLL 中,如果我们使用了 __stdcall 调用约定,函数名会被修饰以包含 ‘@’ 字符以及函数参数所占字节数。例如,如果你有一个 __stdcall 导出函数 RunGame,它接收一个指针作为参数,所以在 32 位 DLL 中,它将被修饰为 _RunGame@4。然而,在 64 位 DLL 中,无论你使用哪种调用约定(__cdecl__stdcall 或其他),名字都不会被修饰。所以,在 64 位 DLL 中,你的 RunGame 函数名在导出时会保持不变,即 RunGame。这就是为什么你会发现同样的函数在 32 位 DLL 中被修饰,而在 64 位 DLL 中却不会被修饰。这主要归因于 Windows 平台对 32位和 64位 DLL 导出函数的处理方式有所不同。
在windows下使用golang调用C语言dll时候需要注意的几点:
  1. golang build位数要和dll位数相同,即要么都是32位,要么都是64位。
  2. windows默认是__stdcall,go默认是____cdecl
  3. win32位下的dll函数名会增加修饰,那么边以后的导出函数名到底是什么,可以把dll扔到Dependency Walker里边查看。
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值