You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GSF转XTF格式Python脚本加载gsfpy库失败求助

GSF转XTF Python脚本运行错误排查与解决

问题背景

我编写了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:
    1. 右键「此电脑」→ 属性 → 高级系统设置 → 环境变量
    2. 新建系统变量,变量名填GSFPY3_08_LIBGSF_PATH,变量值填libgsf.dll的绝对路径(如C:\libs\libgsf.dll)
    3. 重启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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 23:27:20