基于Python调用封装Hansoft-SDK经验分享

326 阅读3分钟

背景:

目前游戏行业内的很多团队采用Hansoft作为团队敏捷规划工具,Hansoft的开发商Perforce,能很好的和P4V协作,所以得到了很多国外公司的青睐,国内虽然不是很多,但是也有一些团队在使用。

在团队项目中,我们会对协作工具做一些DIY需求,经常会使用SDK来封装一些自己的服务来支持团队需求,以提高工作效率,但我作为国内开发者,在使用该工具的SDK的过程充满了痛苦和折磨,最大的原因就是几乎没有关于HansoftSDK的开发者的经验分享,以及它晦涩的开发文档,除此外,SDK仅支持C/C++、Java、C#/.NET,Python也是最近的版本才支持,但并不为官方所推荐和维护,所以开发过程中充满了各种各样的困难,为了避免其他开发者走同样的弯路,我将遇到的问题和一些代码整理下来供有同样问题面临的同学参考,希望能提供一点微小的帮助。

首先整理了一些官方文档:

1.官方文档:HansoftSDK

sdk库文件下载地址:Hansoft SDK | Perforce

下载好与你访问的Hansoft版本一致的sdk压缩包后,解压取出'HPMSdkManaged_4_5.x64.dll'文件放在与你的代码文件一致的目录下。我是用的是Hansoft11版本。

如果想调用sdk访问Hansoft数据库,首先需要一个在后台创建一个SDK账户,并如下图所示配置在代码中或配置文件中。

image.png

通过PIP安装一些必备的包:pythonnet 2.5.2 如果版本不一致有可能会报错或无法访问dll.

以下是Hansoft官方提供的Python样例代码。只包括基础的与Hansoft建立连接功能。

`#!/usr/bin/python

-- coding: utf-8 --

import sys

import clr from System import IntPtr from System import String from System import IO from System import Array from System.Collections import *

dll_path = 'path/to/HPMSdkManaged_4_5.x64' #不能有.dll后缀 clr.AddReference( dll_path ) import HPMSdk

SERVER_NAME = 'hansoft' PORT_NO = 50256 DATABASE_NAME = 'Company Projects' USER_NAME = 'SDKUser' PASSWORD = 'hpmadm'

class SessionCallbacks(HPMSdk.HPMSdkCallbacks): namespace = "SessionCallbacks" def init( self ): super(HPMSdk.HPMSdkCallbacks, self).init()

def On_ProcessError( self, inError ):
    print 'SessionCallbacks.On_ProcessError:', inError

class Hansoft( object ): def init( self, server_name=SERVER_NAME ): self.session = None self.server_name = server_name self.project_id = -1 self.project_name = '' def del( self ): self.sessionDestroy()

def sessionOpen( self ):
    self.ensureConnected()

def _sessionOpenMain( self ):
    callback = None

    try:
        callback = SessionCallbacks()
        self.session = HPMSdk.HPMSdkSession.SessionOpen( self.server_name, PORT_NO, DATABASE_NAME, USER_NAME, PASSWORD, callback, None, True, HPMSdk.EHPMSdkDebugMode.Off, IntPtr.op_Explicit(0), 0, "", "", None )
    except HPMSdk.HPMSdkException, e:
        print 'HPMSdk.HPMSdkException'
        print e.ErrorAsStr()
        pass
    except HPMSdk.HPMSdkManagedException, e:
        print 'HPMSdk.HPMSdkManagedException'
        print e.ErrorAsStr()
        pass
    except Exception, e:
        print e

def ensureConnected( self, force=False ):
    try:
        if self.session:
            self.session.ResourceEnum()
    except HPMSdk.HPMSdkException, e:
        print e.ErrorAsStr()
        self.sessionDestroy()
    except HPMSdk.HPMSdkManagedException, e:
        print e.ErrorAsStr()
        self.sessionDestroy()
    except Exception, e:
        print e
        self.sessionDestroy()

    if self.session:
        return

    self._sessionOpenMain()
    if self.project_name != '':
        self.setProject( self.project_name )

def sessionDestroy( self ):
    if self.session is not None:
        try:
            HPMSdk.HPMSdkSession.SessionDestroy( self.session )
        except HPMSdk.HPMSdkException, e:
            print 'sessionDestroy : HPMSdk.HPMSdkException:', e.ErrorAsStr()
        except HPMSdk.HPMSdkManagedException, e:
            print 'sessionDestroy : HPMSdk.HPMSdkManagedException:',e.ErrorAsStr()
        except Exception, e:
            pass
        self.session = None

def test(): h = Hansoft() h.sessionOpen() h.sessionDestroy()

EOD`

run后返回Hansoft connect success即为访问成功,可以开展下一步的工作。

重要!!!!在这一行代码中,self.session = HPMSdk.HPMSdkSession.SessionOpen( self.server_name, PORT_NO, DATABASE_NAME, USER_NAME, PASSWORD, callback, None, True, HPMSdk.EHPMSdkDebugMode.Off, IntPtr.op_Explicit(0), 0, "", "", None ),倒数第二个参数是DLL的目录,在我们下载官方SDK下有个Win32目录,这个也是我们必须要填的,比如“C:/Windows/HansoftSDK/Win32”,否则有可能出现英文报错“找不到DLL目录。”

这里困扰了我很久,之前我以为是因为只支持Python2,导致我代码重构,最近才发现,原来是因为这里的问题。

Q&A:

在调用的过程中可能存在以下需要注意点:

1.如下图中显示报错 Unresolved reference 'System'.

image.png

忽视即可,原因是通过该代码的实现方案是通过Pythonnet包跨语言调用C#的.dll文件实现

2.pythonnet版本需要为2.5.2

3.使用try except代码块捕获异常时,需要如下图红框所示捕获异常,否则会无法正确显示报错内容。

image.png

4.HansoftSDK版本要和Hansoft服务器的版本一致。之前我因为这个问题卡了很久,才排查出来是这个原因。

备注:如何下载到旧版本SDK:

image.png

后面我会介绍一些SDK中的常用的方法,以及对应的操作。