Hellojxl - P/Invoke
type: channel
link: https://hellojxl.com/index.php/tag/P-Invoke/
items: 解决p/invoke在Linux下的段错误问题

解决p/invoke在Linux下的段错误问题
type: item
date: 2023-03-19T13:56:00+00:00
description: 前言最近公司打算将操作系统迁移到Linux环境下，于是调研了一下现有引用类库的情况，项目中有个最主要的引用是国产的TLQ，多个项目引用了，看了一下TLQ的介绍，本身就是跨平台的，不过公司在用的是官方给的.net framework版本，本身不是跨平台的，经过协商，对方把源码发了过来，改为.net standard2.0也编译通过了，在Linux下却出问题了。Lib引用对于源码中所有P/invoke相关的将dll去掉，在Linux系统下，会自动查找lib开头的类库，如果仍然查找不到，就要设置类库的加载位置了，很简单，一共两种方式，一种是增加LD_LIBRARY_PATH的环境变量，一种是编辑/etc/ld.so.conf文件，增加类库目录，由于网上讲解很多，不再赘述。内存对齐遇到的最大问题是在Windows下一切正常，但是在Linux下会报段错误，第一次遇到的时候还很懵逼，后来查了一下原来是指针越界或重复释放内存之类的操作，刚开始的时候由于改动了代码，一直以为是自己改出来的问题，尝试了很多方式都一无所获，后来又经过协商才发现跟自己的改动完全没有关系，问题是出在了一个结构体上，这个结构体一直没有动过，所以没有往这个方向去想，并且项目是在收消息的时候才出现的错误，且只有在第二次收消息的时候才会出段错误，经过了半天调试依然没有头绪，就在快要放弃时突然发现原来类库方为了做跨平台在引用线程时增加了区分，windows下用的int32来代替线程id，Linux下则直接用的Thread_t，那么Thread_t在Linux下是什么类型呢？网上查了一下，果然跟Windows不一样，类型为uint64_t，对应的c#格式为：ulong。查到这个答案的时候心里并没有在意，因为前面已经尝试过n种方法了，但是在改动完之后在Linux上测试，奇迹却出现了，完全正常了。结束原本一直以为运行时在进行底层调用时对Intptr进行了改动，造成的指针错误，后来才发现原来是自己错了，如果项目中再出现段错误了，那么就要仔细对比每个数据类型了，通常是类型封送错了。