gon*_*utz 6 windows com dll go
我在 Go 中创建了一个Direct3D9 包装器,它使用 CGo 与 C 中的 COM 对象进行交互。
我想摆脱 Windows 下对 C 编译器的依赖,这样用户就不必安装 MinGW 或 Cygwin 来使用 Go 中的 DirectX。
问题是 d3d9.dll 不公开 C 函数,而是使用 COM。syscall.LoadLibrary("d3d9.dll")加载 DLL(使用)后唯一可以直接调用的函数是Direct3DCreate9. 这将返回一个 COM 对象,该对象将所有功能公开为方法。
如何在没有 CGo 的情况下从纯 Go 调用 DLL 中的 COM 对象方法?
我知道Go-OLE库,它声明它无需 CGo 即可调用 COM 接口,但我无法从源代码中了解如何为 Direct3D9 做同样的事情。一个仅包含相关部分的简单示例会有很大帮助。
我问了 go-ole 的人,就像 @kostix 所建议的那样。
这是解决方案:
d3d9 一般没有 COM vtbl。例如,它没有 IDispatch 接口。所以你不能对 d3d9 使用 go-ole。但是你可以通过用 go 编写所有接口来做到这一点。
package main
import (
"fmt"
"log"
"syscall"
"unsafe"
)
const (
D3D9_SDK_VERSION = 32
)
var (
libd3d9 = syscall.NewLazyDLL("d3d9.dll")
procDirect3DCreate9 = libd3d9.NewProc("Direct3DCreate9")
)
type IDirect3D struct {
lpVtbl *IDirect3DVtbl
}
type IDirect3DVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
RegisterSoftwareDevice uintptr
GetAdapterCount uintptr
GetAdapterIdentifier uintptr
GetAdapterModeCount uintptr
EnumAdapterModes uintptr
GetAdapterDisplayMode uintptr
CheckDeviceType uintptr
CheckDeviceFormat uintptr
CheckDeviceMultiSampleType uintptr
CheckDepthStencilMatch uintptr
CheckDeviceFormatConversion uintptr
GetDeviceCaps uintptr
GetAdapterMonitor uintptr
CreateDevice uintptr
}
func (v *IDirect3D) AddRef() int32 {
ret, _, _ := syscall.Syscall(
v.lpVtbl.AddRef,
1,
uintptr(unsafe.Pointer(v)),
0,
0)
return int32(ret)
}
func (v *IDirect3D) Release() int32 {
ret, _, _ := syscall.Syscall(
v.lpVtbl.Release,
1,
uintptr(unsafe.Pointer(v)),
0,
0)
return int32(ret)
}
func (v *IDirect3D) GetAdapterCount() uint32 {
ret, _, _ := syscall.Syscall(
v.lpVtbl.GetAdapterCount,
1,
uintptr(unsafe.Pointer(v)),
0,
0)
return uint32(ret)
}
func main() {
v, r, err := procDirect3DCreate9.Call(uintptr(D3D9_SDK_VERSION))
if r != 0 && err != nil {
log.Fatal(err)
}
d3d := *((**IDirect3D)(unsafe.Pointer(&v)))
d3d.AddRef()
defer d3d.Release()
fmt.Println(d3d.GetAdapterCount())
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2371 次 |
| 最近记录: |