我需要在golang中将字符串作为参数传递给C DLL,我希望得到这样的结果:
proc, e = syscall.GetProcAddress(h, "JLINKARM_ExecCommand") //One of the functions
vals := []string{"device = STM32F429ZI"}
start := uintptr(unsafe.Pointer(&vals[0]))
asd, _, _ = syscall.Syscall6(uintptr(proc), 3, start, 0, 0, 0, 0, 0)
Run Code Online (Sandbox Code Playgroud)
但它不起作用.Syscall采取param uintptr.我不能使用C包,因为它不会在Windows上构建.
在C中它的工作原理如下:
strcpy(acIn, "device = STM32F407IE");
JLINKARM_ExecCommand(acIn, &acOut[0], sizeof(acOut));
Run Code Online (Sandbox Code Playgroud)
那么C DLL是否可以获得字符串参数并正确使用它?
要将字符串传递给syscall,您需要将指针传递给字符串的第一个字符.第一个问题是你的DLL函数需要什么字符串编码.Go字符串被编码为UTF-8 unicode,因此如果您的C函数需要其他东西,您必须先将其转换.以下是一些常见情况:
假设您的C函数需要一个以零结尾的ASCII字符串,那么您可以执行以下操作:
s := "some string"
b := append([]byte(s), 0)
syscall.Syscall(uintptr(proc), 1, uintptr(unsafe.Pointer(&b[0])), 0, 0)
Run Code Online (Sandbox Code Playgroud)
首先将您的字符串转换为字节数组,然后添加C期望的结果.然后将指针传递给第一个字节字符.
为了安全起见,您还应确保实际只传入有效的ASCII字符串且没有无效字符.通常只有[0..127]范围内的字符对通用ASCII有效.其余的取决于当前的代码页.
如果您调用Windows DLL,您通常需要使用其功能的UTF-16版本,例如SendMessageW,因此需要将您的字符串转换为UTF-16.幸运的是,在Windows下有一个包装函数,所以你可以执行以下操作:
s := "some string"
s16, err := syscall.UTF16PtrFromString(s)
if err == nil {
syscall.Syscall(uintptr(proc), 1, uintptr(unsafe.Pointer(s16)), 0, 0)
}
Run Code Online (Sandbox Code Playgroud)
这将转换为UTF-16并在最后为您追加预期的零.
归档时间: |
|
查看次数: |
665 次 |
最近记录: |