使用Go而不是Python在Matlab中使用DLL。

huangapple go评论82阅读模式
英文:

Using Matlab DLL in Go instead Python

问题

我正在使用由Matlab Simulink/Codegen生成的DLL模型。

这段代码在Python中运行得很好:

import ctypes
real_T = ctypes.c_double

# 导入DLL
dll = ctypes.windll.LoadLibrary("./simulink.dll")

# 模拟
dll.initialize()     # 初始化
for i in range(10):
   mdlInput = real_T.in_dll(dll, "my_custom_input")
   mdlInput.value = i
   # 步进
   dll.step() # 步进
   # 获取输出
   mdlOutput = real_T.in_dll(dll, "my_custom_output")
   print(mdlOutput.value)
dll.terminate() # 结束模拟

我只想将上面的代码翻译成Go语言以提高性能。问题是syscall.syscall不识别real_T (C.Double)类型,无法返回double而不是指针。

在Go语言中如何设置"my_custom_input"的值并读取"my_custom_output"的值?

英文:

I'm using a DLL model generated by Matlab Simulink/Codegen.

The code works pretty well in Python:

import ctypes
real_T = ctypes.c_double

# Importa a DLL
dll = ctypes.windll.LoadLibrary("./simulink.dll")

# Simulate
dll.initialize()     # Init
for i in range(10):
   mdlInput = (real_T).in_dll(dll, "my_custom_input")
   mdlInput.value = i
   # Step
   dll.step() # step
   # get output
   mdlOutput = (real_T).in_dll(dll, "my_custom_output")
   print(mdlOutput.value)
dll.terminate() # end of simulation

I just want to translate the code above to Go to increase performance. The problem is that syscall.syscall does not recognize the real_T (C.Double) type to return a double instead of a pointer.

How do I set the "my_custom_input" value and read the "my_custom_output" value in Go?

答案1

得分: 1

刚刚发现了一种使用LazyDll的新解决方案。
完整的代码如下:

package main

import (
	"log"
	"syscall"
	"unsafe"
)

func main() {
	dll := syscall.NewLazyDLL(".\\simulink.dll") // 使用LazyDll加载DLL
	dll.NewProc("initialize").Call() // 调用DLL中的initialize方法
	// 现在获取自定义输入的指针
	customInput := (*float64)(unsafe.Pointer(dll.NewProc("my_custom_input").Addr()))
	// 更新自定义输入的值
	*customInput = 1.23
	// 调用DLL中的step方法
	dll.NewProc("step").Call() // 调用DLL中的step方法
	// 现在获取自定义输出的指针并显示其值
	customOutput := (*float64)(unsafe.Pointer(dll.NewProc("my_custom_output").Addr()))
	// 打印输出的值
	log.Print(*customOutput)
	// 终止DLL的执行
	dll.NewProc("terminate").Call() // 调用DLL中的terminate方法
}

以上是要翻译的内容。

英文:

Just found a new solution using LazyDll.
The complete code as:

package main

import (
	"log"
	"syscall"
	"unsafe"
)

func main() {
	dll = syscall.NewLazyDLL(".\\simulink.dll") // Load DLL as LazyDll
	dll.NewProc("initialize").Call() // Call initialize method from dll
	// Now get pointer to custom input
	customInput := (*float64)(unsafe.Pointer(dll.NewProc("my_custom_input").Addr()))
	// Update custom Input Value
	*customInput := 1.23
	// Call the step method from dll
	dll.NewProc("step").Call() // Call step method from dll
	// Now get pointer to custom output and show it's value
	customOutput := (*float64)(unsafe.Pointer(dll.NewProc("my_custom_output").Addr()))
	// Print the value of output
	log.Print(*customOutput)
	// Terminate the dll execution
	dll.NewProc("terminate").Call() // Call terminate method from dll
}

huangapple
  • 本文由 发表于 2023年3月8日 00:26:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75664650.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定