dongpao5658 2019-05-12 15:04
浏览 97

从Go调用DLL-我在做什么错?

I'm trying to convert a program from Python (2.7, 32-bit) to Go (1.12.5, 32bit), and failing miserably with an access violation. The program calls a function in a 32-bit dll (ehlapi32.dll).

The following clips of the Python code appear to work perfectly (I'm not affirming that they are correct!):

class ehlapi32:
    hllDll       = "C:\Program Files (x86)\IBM\Personal Communications\EHLAPI32.dll"
    hllDll       = ctypes.WinDLL(hllDll)
    hllApiProto  = ctypes.WINFUNCTYPE(ctypes.c_int,ctypes.c_void_p,ctypes.c_void_p,
                                      ctypes.c_void_p,ctypes.c_void_p)
    hllApiParams = (1, "p1", 0), (1, "p2", 0), (1, "p3",0), (1, "p4",0),
    hllApi       = hllApiProto (("HLLAPI", hllDll), hllApiParams)
    pFunConnect  = ctypes.c_int(1)
...
    def connect(self):
        shlSession = self.session + b'\0\0\0'
        pText      = ctypes.c_char_p (shlSession)
        pLength    = ctypes.c_int (len(shlSession))
        pReturn    = ctypes.c_int (13)

        ehlapi32.hllApi (ctypes.byref (ehlapi32.pFunConnect), pText,
                         ctypes.byref (pLength), ctypes.byref (pReturn))

Now here's what I'm trying as the Go equivalent. This fails:

// ElFunc: EHLLAPI Functions
type ElFunc uint32

const (
    eConnect    ElFunc = 1  // Connect to a terminal
)
...
// Session: a 3270 session handle
type Session struct {
    SessId  string
    SysId   string
    Entry   string
    Result  []string
    Headers int
    Footers int
    Rows    int
    Cols    int
    Scroll  int
    Proc    *syscall.LazyProc
}
...
func (s Session) Connect() uint32 {
    // Load EHLLAPI DLL
    dll := syscall.NewLazyDLL(dllName)
    s.Proc = dll.NewProc(dllProc)
    // Connect to session
    rc := s.ecall(eConnect, s.SessId, 1, 0)
    if rc == 0 {
        defer s.Disconnect()
    }
...
// ecall: provides simplified EHLLAPI DLL calls

func (s Session) ecall(fun ElFunc, buffer string, count uint32, ps uint32) uint32 {
    rc := ps
    _, _, _ = s.Proc.Call(
        uintptr(unsafe.Pointer(uintptr(uint32(fun)))),
        uintptr(unsafe.Pointer(&buffer)),
        uintptr(unsafe.Pointer(uintptr(count))),
        uintptr(unsafe.Pointer(uintptr(rc))),
    )
    return rc
}

The failure looks like an access violation at s.Proc.Call in ecall().

I realise that syscall is deprecated; I have also tried with golang.org/x/sys/windows, without success. I have no constraints as to which I use.

I'll confess I'm way out of my depth here.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 目详情-五一模拟赛详情页
    • ¥15 有了解d3和topogram.js库的吗?有偿请教
    • ¥100 任意维数的K均值聚类
    • ¥15 stamps做sbas-insar,时序沉降图怎么画
    • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
    • ¥15 关于#Java#的问题,如何解决?
    • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
    • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
    • ¥15 cmd cl 0x000007b
    • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line