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

Linux下Python调用SAP NW RFC出现LP_RFC_CONNECTION_PARAMETER类型不匹配错误

问题:Python调用SAP NetWeaver RFC库从Windows迁移到Linux后参数类型错误

从SAP官方博客获取的Python调用SAP NetWeaver RFC库的代码在Windows上运行正常,迁移到Linux环境时仅将windll.LoadLibrary(SAPNWRFC)替换为cdll.LoadLibrary(SAPNWRFC),却出现如下错误:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    data = dataProcessing("USR01")
  File "src/utils.py", line 4, in dataProcessing
    queryData = query(table)
  File "src/readTable.py", line 9, in query
    hRFC = SAP.RfcOpenConnection(connection(), 5, RfcErrInf)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP_RFC_CONNECTION_PARAMETER_Array_5 instance instead of RFC_CONNECTION_PARAMETER_Array_5

相关代码

sapnwrfc.py 核心代码

from ctypes import *
import platform, os

#-Structures------------------------------------------------------------
class RFC_ERROR_INFO(Structure):
    _fields_ = [("code", c_long),
                ("group", c_long),
                ("key", c_wchar * 128),
                ("message", c_wchar * 512),
                ("abapMsgClass", c_wchar * 21),
                ("abapMsgType", c_wchar * 2),
                ("abapMsgNumber", c_wchar * 4),
                ("abapMsgV1", c_wchar * 51),
                ("abapMsgV2", c_wchar * 51),
                ("abapMsgV3", c_wchar * 51),
                ("abapMsgV4", c_wchar * 51)]

class RFC_CONNECTION_PARAMETER(Structure):
    _fields_ = [("name", c_wchar_p),
                ("value", c_wchar_p)]

#-Constants(省略部分常量定义)-------------------------------------------------------------

#-Variables-------------------------------------------------------------
ErrInf = RFC_ERROR_INFO; RfcErrInf = ErrInf()
ConnParams = RFC_CONNECTION_PARAMETER * 5; RfcConnParams = ConnParams()
SConParams = RFC_CONNECTION_PARAMETER * 3; RfcSConParams = SConParams()

#-Library---------------------------------------------------------------
if str(platform.architecture()[0]) == "32bit":
  os.environ['PATH'] += ";/home/marilan/Nunes/Klyra/nwrfcsdk/lib"
  SAPNWRFC = "/home/marilan/nwrfcsdk/lib/libsapnwrfc.so"
elif str(platform.architecture()[0]) == "64bit":
  os.environ['PATH'] += ";/home/marilan/Nunes/Klyra/nwrfcsdk/lib"
  SAPNWRFC = "/home/marilan/nwrfcsdk/lib/libsapnwrfc.so"

SAP = cdll.LoadLibrary(SAPNWRFC)

#-Prototypes------------------------------------------------------------
# 省略其他函数原型定义
SAP.RfcOpenConnection.argtypes = [POINTER(ConnParams), c_ulong, POINTER(ErrInf)]
SAP.RfcOpenConnection.restype = c_void_p

connection() 函数代码

from sapnwrfc import *

def connection():
    FileName = "sapnwrfc.py"
    exec(compile(open(FileName).read(), FileName, "exec"))
    #-Connection parameters-------------------------------------------------
    RfcConnParams[0].name = "ASHOST"; RfcConnParams[0].value = "I put my credentials here"
    RfcConnParams[1].name = "SYSNR" ; RfcConnParams[1].value = "I put my credentials here"
    RfcConnParams[2].name = "CLIENT"; RfcConnParams[2].value = "I put my credentials here"
    RfcConnParams[3].name = "USER"  ; RfcConnParams[3].value = "I put my credentials here"
    RfcConnParams[4].name = "PASSWD"; RfcConnParams[4].value = "I put my credentials here"

    return RfcConnParams

解决方案

错误核心是Windows和Linux下ctypes处理数组指针的逻辑差异:Windows的windll会自动将数组转为指针传递,但Linux的cdll需要显式传递指针。需做以下修改:

1. 修正RfcOpenConnection的参数类型定义

将原代码中:

SAP.RfcOpenConnection.argtypes = [POINTER(ConnParams), c_ulong, POINTER(ErrInf)]

修改为:

SAP.RfcOpenConnection.argtypes = [POINTER(RFC_CONNECTION_PARAMETER), c_ulong, POINTER(RFC_ERROR_INFO)]

直接指定数组元素的指针类型,而非数组的指针类型。

2. 调用时显式传递指针

将调用代码:

hRFC = SAP.RfcOpenConnection(connection(), 5, RfcErrInf)

修改为:

params = connection()
hRFC = SAP.RfcOpenConnection(byref(params), 5, byref(RfcErrInf))

使用byref()函数显式获取数组和错误信息结构体的指针。

3. 移除connection()函数中的冗余代码

删除connection()里重复加载模块的exec语句,直接使用导入的变量:

from sapnwrfc import RfcConnParams

def connection():
    #-Connection parameters-------------------------------------------------
    RfcConnParams[0].name = "ASHOST"; RfcConnParams[0].value = "你的ASHOST地址"
    RfcConnParams[1].name = "SYSNR" ; RfcConnParams[1].value = "你的系统编号"
    RfcConnParams[2].name = "CLIENT"; RfcConnParams[2].value = "你的客户端编号"
    RfcConnParams[3].name = "USER"  ; RfcConnParams[3].value = "你的用户名"
    RfcConnParams[4].name = "PASSWD"; RfcConnParams[4].value = "你的密码"

    return RfcConnParams

内容的提问来源于stack exchange,提问作者Nathan Nunes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:33:30