I thought I was going nuts when a really not that complicated API I was declaring into did not want to work on all methods that were using CStrings as input parameters. Until I found that neither a TypeCast from String to CString nor implicit conversion would append a trailing 0 byte to the converted string, in other words, what I thought to be a CString was technically still a normal string.
Which I would consider a bug. Is this documented or was it already declared as no bug, but a feature?
Declares will work if I extend the Cstring manually (or create a memory block sized one bytes larger than input string). With an implicitely converted string, they will fail.
Agreed terminator does not have to be part of the variable in debugger. But seeing that declares with such CStrings fail while they will work with a manually constructed CString from MemoryBlock, I consider this a bug.
Sadly current project needs a measurement instrument, so I cannot build a sample project for Xojo they could check.
Sure. This is how a declare into the API I am using works (using DeclareFunctionMBS):
var p As Ptr = ExtLib.Symbol("Execute")
var f As New DeclareFunctionMBS("(p)Z", p)
var para As New MemoryBlock(command.Length + 1)
para.StringValue(0, command.Length) = command
var p1 As Ptr = para
f.SetParameters(p1)
Var s As String = f.Invoke
If s.isempty Then
MakeDeviceError(CurrentMethodName + " empty result: " + command)
Else
…
Officially the method expects a CString. So this should be ok, but it will not work:
var p As Ptr = ExtLib.Symbol("Execute")
var f As New DeclareFunctionMBS("(Z)Z", p)
var para As CString = command
f.SetParameters(para)
Var s As String = f.Invoke
If s.isempty Then
MakeDeviceError(CurrentMethodName + " empty result: " + command)
Else
…
A typeCast (f.setParameters(CType(command, CString)) will also fail.
There’s no place for implicit conversions here. Using pointers, the parameters must be explicitly defined, pointing to a data area where you placed your contents, that should be CStrings, and they don’t.