Ubuntu下Go构建的test.so动态库无法被.NET调用的问题
问题解决:.NET DllImport找不到Go编译的so库入口
原因分析
C程序能正常调用但.NET失败,核心原因集中在三点:
- Go编译的共享库符号名称与.NET查找的名称不匹配(即便使用
//export,仍需确认实际导出符号) - .NET调用约定与Go导出的C函数约定不匹配
- .NET程序未正确定位到
test.so文件
排查与解决步骤
1. 确认Go编译命令正确
必须使用c-shared模式编译,才能生成C兼容的共享库,执行以下命令:
go build -buildmode=c-shared -o test.so test.go
若此前使用其他编译模式(如c-archive),会导致符号无法正确对外导出。
2. 检查共享库的导出符号
执行命令查看test.so的实际导出符号:
nm -D test.so | grep TestSay
正常输出应类似:
0000000000001190 T TestSay
如果输出符号名是_TestSay(带下划线),则需将.NET代码的EntryPoint改为_TestSay。
3. 修正.NET的DllImport配置
Go导出的C函数默认使用cdecl调用约定,需在.NET的DllImport中明确指定,同时确保库路径可被程序访问:
using System.Runtime.InteropServices; namespace hello_web { public class Test { // 明确指定调用约定,同时确保库路径正确 [DllImport("./test.so", EntryPoint = "TestSay", CallingConvention = CallingConvention.Cdecl)] public static extern void TestSay(); public static void GetTestAdd() { TestSay(); } } }
- 若
test.so不在程序当前工作目录,可使用绝对路径,或通过设置LD_LIBRARY_PATH环境变量指向test.so所在目录。
4. 验证.NET程序运行环境
运行.NET程序时需确保:
- 程序拥有读取
test.so的权限 - 系统已安装Go运行时依赖(若编译时未静态链接相关库)
验证测试
修改后重新编译.NET程序并运行,即可成功调用Go导出的TestSay函数。
内容的提问来源于stack exchange,提问作者Pomelo
相关产品推荐
相关产品推荐

