- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我创建了一个 Direct3D9 wrapper在 Go 中,它使用 CGo 与 C 中的 COM 对象进行交互。
我想摆脱对 Windows 下 C 编译器的依赖,这样用户就不必安装 MinGW 或 Cygwin 就可以从 Go 中使用 DirectX。
问题是 d3d9.dll 不公开 C 函数而是使用 COM。加载 DLL 后可以直接调用的唯一函数(使用 syscall.LoadLibrary("d3d9.dll")
)是 Direct3DCreate9
。这将返回一个 COM 对象,它将所有功能公开为方法。
如何在没有 CGo 的情况下从纯 Go 调用 DLL 中的 COM 对象方法?
我知道 Go-OLE库声明它在没有 CGo 的情况下调用 COM 接口(interface),但我无法从源代码中看到我将如何为 Direct3D9 做同样的事情。一个仅包含相关部分的简单示例会有很大帮助。
最佳答案
我问了 go-ole 的人,就像@kostix 建议的那样。
解决方法如下:
d3d9 doesn't have generally COM vtbl. for example, it doesn't have IDispatch interface. So you can't use go-ole for d3d9. But you can do it with writing all interface in 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())
}
关于windows - 在没有 CGo 的情况下从 Go 调用 COM 对象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39162054/
我试图使用 cgo 为 x264 库编写一个小包装器,但遇到了嵌套结构的问题。该库使用了许多复杂的结构,其中一些字段本身就是匿名结构。 当尝试使用 cgo 访问这些结构时,我遇到了编译错误,因为 go
我正在使用一个 C 库,与下面不同,我无法控制它。我需要将指向也包含指针的数组的指针传递给 C 函数。 package main /* #include typedef int* pInt; voi
根据 CGO 的文档( https://pkg.go.dev/cmd/cgo ),在实现中有一个已知的错误: Note: the current implementation has a bug. W
我正在尝试使用 CGO 将现有的 Go 包构建到 C 共享库和 header 中. 我用 -buildmode c-shared 构建了这个包如记录。 -buildmode=c-shared
C部分: struct Person {...} struct Person * get_team(int * n) 转到部分: n := C.int(0) var team *C.struct_Pe
我在ubuntu 18上使用go版本go版本“go1.14.4 linux / amd64”。该代码不是我编写的,但我认为它可以与比当前版本早几年的go版本一起使用。当我尝试构建时,出现此错误。有什么
我编写了一个 Go 程序来模拟按键操作。为此,我必须使用 cgo 和不同的 C 代码片段,具体取决于正在编译 Go 代码的操作系统。我编写的代码如下所示: package keyboard /* #i
我已经在 Linux 中围绕信号量函数编写了一个包装器。这在过去的 Go 1.3 和 Go 1.4 上对我有用,但我需要使用这个包装器重建我的应用程序,它不再使用 Go 1.6.2 或 Go 1.7r
关注我的 earlier question ,现在我在尝试执行此 article 中的所有相同步骤时遇到此错误,因为我已经从 Go 1.6.1 升级到 Go 1.7.1(我无法返回到 Go 1.6.1
有时,C API 可能需要 NULL 指针。 这在 CGO 中可能吗? 例如,我想在 Go 语言程序中向 strcmp() 传递一个 null 参数: package strutil /* #incl
我正在使用 native linux C 二进制文件,它有一个相当昂贵的初始化调用,我想在应用程序启动时执行一次。这个调用应该在内部打开一堆文件句柄供以后使用。当我从 Go 调用这个昂贵的初始化 C
我正在使用这个库 https://github.com/billziss-gh/cgofuse ,还有一些接口(interface)需要实现,其中一个看起来像这样: func (self *Memfs
似乎我不能使用 Cgo 调用在另一个目录而不是当前 Go 包中声明的 C 函数。 所有文件的代码: // TestGoCallOC.go package main /* #include "test.
去项目结构 src test.go testc/collection/linkedlist.h testc/collection/linkedlist.c test.go package
我正在用 Go 编写一个库,我正在使用 CGo 将其编译为 native 库,但是当导出函数时,它们在函数声明和文档注释之间有这个烦人的空行。 例如,假设我的 go 文件中有这个 /** * Pri
为什么使用 Cgo 时我的 .go 文件中无法识别 c 函数? 我遵循了所有过程并尝试了 godoc 上的示例,它有效但这个不起作用,是什么原因? 文件夹结构 libsha.a sha.cpp 扫码
我正在用 cgo 包装一个 C 库,以供普通 Go 代码使用。 我的问题是我想将错误字符串向上传播到 Go API,但是有问题的 C 库通过线程本地存储提供错误字符串;有一个全局 get_error(
我有点乱,我看不出我是怎么摆脱它的……我得到了什么:* 我使用 cgo 构建的库 (dll)。* 使用此库 (dll) 的 C++ 应用程序。 我要做什么:我尝试释放在 C++ 应用程序的 cgo 库
我正在用 Go 编写一个库,我想导出到一个 c-shared-library。它工作得很好,但是我发现导出的 header 使用 p0、p1、p2、 有点烦人…… 用于参数名称,而不是 Go 中的原始
我目前正在开发一个程序,该程序使用带有 cgo 的 c 库调用长时间运行的函数。我无法使用 c 编辑库以允许超时。到目前为止,我唯一的解决方案是让僵尸 goroutine 继续运行 func Time
我是一名优秀的程序员,十分优秀!