GSF转XTF格式Python脚本加载gsfpy库失败求助
问题背景
我编写了Python脚本用于将二进制GSF格式文件转换为XTF格式,代码如下:
import os from gsfpy import open_gsf from xtf import XTFFile, XTFPingHeader, XTFPingChannelHeader, XTFPing def convert_gsf_to_xtf(gsf_file_path, xtf_file_path): # Open the GSF file with gsfpy.GSFF(gsf_file_path) as gsf_file: # Create an XTF file and add metadata xtf_file = XTFFile() xtf_file.set_sonar_name("My Sonar") xtf_file.set_recording_program_name("My Program") xtf_file.set_number_of_channels(gsf_file.number_channels) # Loop through each ping in the GSF file for ping_number in range(gsf_file.number_pings): ping_data = gsf_file.read_ping(ping_number) # Create an XTF ping header and add metadata ping_header = XTFPingHeader() ping_header.set_serial_number(ping_data.serial_number) ping_header.set_ping_number(ping_data.ping_number) ping_header.set_number_of_channels(gsf_file.number_channels) ping_header.set_sonar_depth(ping_data.sonar_depth) ping_header.set_frequency(gsf_file.frequency) ping_header.set_sample_rate(gsf_file.sample_rate) ping_header.set_ping_date(ping_data.datetime) # Loop through each channel in the GSF ping for channel_number in range(gsf_file.number_channels): channel_data = ping_data.channels[channel_number] # Create an XTF channel header and add metadata channel_header = XTFPingChannelHeader() channel_header.set_channel_number(channel_data.channel_number) channel_header.set_gain(channel_data.gain) channel_header.set_pulse_length(channel_data.pulse_length) channel_header.set_sample_rate(gsf_file.sample_rate) # Create an XTF ping and add channel data ping = XTFPing() ping.set_channel_data(channel_number, channel_data.data) # Add the channel header and ping to the XTF file ping_header.add_channel_header(channel_header) ping.add_channel(channel_number, channel_header, channel_data.data) # Add the ping header and ping to the XTF file xtf_file.add_ping_header(ping_header) xtf_file.add_ping(ping_header, ping) # Save the XTF file with the same name as the GSF file but with .xtf extension xtf_file_name = os.path.splitext(gsf_file_path)[0] + ".xtf" xtf_file.save(xtf_file_name) # Convert all GSF files in the directory to XTF format gsf_directory = "C:/Users/repco.geo3/Desktop/Working" for file_name in os.listdir(gsf_directory): if file_name.endswith(".gsf"): gsf_file_path = os.path.join(gsf_directory, file_name) convert_gsef_to_xtf(gsf_file_path, gsf_file_path[:-4] + ".xtf")
运行时出现以下错误:
Traceback (most recent call last):
File "C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\site-packages\gsfpy3_08\bindings.py", line 36, in
_libgsf = CDLL(libgsf_abs_path)
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\ctypes_init.py", line 376, in init
self._handle = _dlopen(self._name, mode)
^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [WinError 193] %1 不是有效的 Win32 应用程序
上述异常直接导致以下异常:
Traceback (most recent call last):
File "C:\Users\repco.geo3\Desktop\Working\convert gsf to xtf.py", line 2, in
from gsfpy import open_gsf
File "C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\site-packages\gsfpy_init_.py", line 64, in
mirror_default_gsf_version_submodule(globals())
File "C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\site-packages\gsfpy_init_.py", line 45, in mirror_default_gsf_version_submodule
gsf_submodule = import(gsf_submodule_name, globals_dict, None, ["*"], 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\site-packages\gsfpy3_08_init_.py", line 10, in
from gsfpy3_08.bindings import (
File "C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\site-packages\gsfpy3_08\bindings.py", line 38, in
raise Exception(
Exception: 无法从 C:\Users\repco.geo3\AppData\Local\Programs\Python\Python311\Lib\site-packages\gsfpy3_08\libgsf\libgsf03-08.so 加载共享库。请设置 $GSFPY3_08_LIBGSF_PATH 环境变量指向正确路径,或移除该环境变量以使用默认版本。
Process finished with exit code 1
核心问题分析
WinError 193与.so库加载失败的本质是:Windows系统无法识别Linux/Unix格式的.so共享库,当前gsfpy安装包可能误提供了Linux版本依赖库,或Python环境与库的架构不匹配(如64位Python搭配32位库)。
分步解决步骤
1. 替换Windows兼容的GSF依赖库
- 卸载现有gsfpy:
pip uninstall gsfpy - 获取适配Windows系统、对应Python 3.11版本的64位gsfpy安装包,或单独下载编译好的Windows版
libgsf.dll文件 - 设置环境变量
GSFPY3_08_LIBGSF_PATH:- 右键「此电脑」→ 属性 → 高级系统设置 → 环境变量
- 新建系统变量,变量名填
GSFPY3_08_LIBGSF_PATH,变量值填libgsf.dll的绝对路径(如C:\libs\libgsf.dll) - 重启Python运行环境或终端,使环境变量生效
2. 修正脚本中的语法与逻辑错误
原代码存在多处问题,即使库问题解决后仍会报错,修正后的代码如下:
import os from gsfpy import open_gsf from xtf import XTFFile, XTFPingHeader, XTFPingChannelHeader, XTFPing def convert_gsf_to_xtf(gsf_file_path, xtf_file_path): # Open the GSF file with gsfpy.GSFF(gsf_file_path) as gsf_file: # Create an XTF file and add metadata xtf_file = XTFFile() xtf_file.set_sonar_name("My Sonar") xtf_file.set_recording_program_name("My Program") xtf_file.set_number_of_channels(gsf_file.number_channels) # Loop through each ping in the GSF file for ping_number in range(gsf_file.number_pings): ping_data = gsf_file.read_ping(ping_number) # Create an XTF ping header and add metadata ping_header = XTFPingHeader() ping_header.set_serial_number(ping_data.serial_number) ping_header.set_ping_number(ping_data.ping_number) ping_header.set_number_of_channels(gsf_file.number_channels) ping_header.set_sonar_depth(ping_data.sonar_depth) ping_header.set_frequency(gsf_file.frequency) ping_header.set_sample_rate(gsf_file.sample_rate) ping_header.set_ping_date(ping_data.datetime) # 创建单个Ping对象(每个Ping只创建一次) ping = XTFPing() # Loop through each channel in the GSF ping for channel_number in range(gsf_file.number_channels): channel_data = ping_data.channels[channel_number] # Create an XTF channel header and add metadata channel_header = XTFPingChannelHeader() channel_header.set_channel_number(channel_data.channel_number) channel_header.set_gain(channel_data.gain) channel_header.set_pulse_length(channel_data.pulse_length) channel_header.set_sample_rate(gsf_file.sample_rate) # 添加通道头与数据到Ping对象 ping_header.add_channel_header(channel_header) ping.add_channel(channel_number, channel_header, channel_data.data) # 将Ping头与Ping数据添加到XTF文件 xtf_file.add_ping_header(ping_header) xtf_file.add_ping(ping_header, ping) # 处理完所有Ping后保存XTF文件 xtf_file.save(xtf_file_path) # 转换目录下所有GSF文件为XTF格式 gsf_directory = "C:/Users/repco.geo3/Desktop/Working" for file_name in os.listdir(gsf_directory): if file_name.endswith(".gsf"): gsf_file_path = os.path.join(gsf_directory, file_name) xtf_file_path = os.path.splitext(gsf_file_path)[0] + ".xtf" convert_gsf_to_xtf(gsf_file_path, xtf_file_path)
主要修正点:
- 修复函数名拼写错误:
convert_gsef_to_xtf改为convert_gsf_to_xtf - 修正循环缩进问题:Ping循环内的代码统一缩进
- 调整XTFPing对象创建时机:每个Ping只创建一次,避免重复覆盖
- 移动文件保存逻辑:将
xtf_file.save()放入函数内部的with块之后,确保对象有效
3. 验证Python环境架构
打开Python终端,执行以下命令确认环境为64位:
import platform; print(platform.architecture())
输出应为('64bit', 'WindowsPE'),确保所有依赖包均为对应64位版本,避免架构不匹配导致的加载错误
内容的提问来源于stack exchange,提问作者Paul S

