将字符串传递给Syscall(uintptr)

I need to pass string as param to C DLL in golang, i want to get something like this:

  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) 

but it doesn't work. Syscall take as param uintptr. I can't use C package because it won't build on windows.

In C it works like:

strcpy(acIn, "device = STM32F407IE");

JLINKARM_ExecCommand(acIn, &acOut[0], sizeof(acOut));

So it is any chance that C DLL can get string param and use it properly?

To pass a string to syscall you need to pass a pointer to the first character of the string. The first question is what string encoding your DLL function expects. Go strings are encoded as UTF-8 unicode so if your C function expects something else you have to convert them first. Here are some common cases:

1) ASCII string

Say your C function expects a zero-terminated ASCII string, then you can do the following:

s := "some string"
b := append([]byte(s), 0)
syscall.Syscall(uintptr(proc), 1, uintptr(unsafe.Pointer(&b[0])), 0, 0)

First convert your string to a byte array and add the zero that C expects at the end. Then pass the pointer to the first byte character.

To be safe you should also make sure that you actually pass in only valid ASCII strings and no invalid characters. Usually only characters in the range [0..127] are valid for general ASCII. The rest depends on the current codepage.

2) UTF-16 on Windows

If you call into a Windows DLL you want to usually use their UTF-16 version of that function, e.g. SendMessageW, and thus need to convert your string to UTF-16. Luckily there is a wrapper function for that under Windows, so you can just do the following:

s := "some string"
s16, err := syscall.UTF16PtrFromString(s)
if err == nil {
    syscall.Syscall(uintptr(proc), 1, uintptr(unsafe.Pointer(s16)), 0, 0)
}

This will convert to UTF-16 and append the expected zero at the end for you.