从Go调用DLL-我做错了什么?
我试图将一个程序从Python(2.7,32位)转换为Go(1.12.5,32位),但由于访问冲突而失败。该程序调用32位dll(ehlapi32.dll)中的函数 下面的Python代码片段似乎工作得很好(我不能肯定它们是正确的!): 现在,这是我正在尝试的,作为围棋的等价物。这失败了:从Go调用DLL-我做错了什么?,go,dll,Go,Dll,我试图将一个程序从Python(2.7,32位)转换为Go(1.12.5,32位),但由于访问冲突而失败。该程序调用32位dll(ehlapi32.dll)中的函数 下面的Python代码片段似乎工作得很好(我不能肯定它们是正确的!): 现在,这是我正在尝试的,作为围棋的等价物。这失败了: // ElFunc: EHLLAPI Functions type ElFunc uint32 const ( eConnect ElFunc = 1 // Connect to a ter
// 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
}
在ecall()
中的s.Proc.Call
处,故障看起来像是访问冲突
我意识到syscall
已被弃用;我也尝试过使用golang.org/x/sys/windows
,但没有成功。我对使用哪一种没有任何限制
我承认我在这方面做得太过火了。当rc==0时,延迟激活。关键是,将延迟放在其他任何事情之前,因为当您发生错误时,连接将保持打开状态,并将给出奇怪的结果。重新启动计算机是关闭连接的唯一选项。@Dippo您是指EHLAPI Connect/Disconnect吗?或者一些普通的东西。延迟是为了确保与PC3270的会话关闭;如果连接未成功,则没有意义。必须用Println替换延迟。延迟必须是主过程中的第一行。因此,当出现问题时,延迟必须启动以删除与dll连接有关的所有内容。这里可以找到一个例子:另外,我认为函数ecall有问题,一旦调用dll,rc永远不会被覆盖。
// 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
}