Shouldn’t a TypeCast to CString create a real Cstring?

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?

u cast string to cstring like this from docu?

You can assign a String variable to a CString and it will be terminated with a null automatically.

Var s As String = "Hello!"
Var cs As CString = s

btw. the docu for cstring need a revised text.

or was it already declared as no bug, but a feature? by design :joy: :zipper_mouth_face:

see debugger show Var b As CString as b As String!? (binary view is useless then)

That’s what I expected, but this is the result:

Bild 04.04.24 um 11.48

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.

BTW: And I never noticed a CString is shown as string in debugger. ??!!

we would expect CString in the Selectbox + 00 in binary output.

The null is a terminator, it’s not really part of the string, we know it is at the proper offset, but it is not part of the real content.

That means

cstringA = “aaa” // internally aaa\0
stringB = cstringA // “aaa” , the null is not part of the string

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.

I simply don’t get your problem. Can you explain with an example?

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.

Sadly using plugins is not a good example because it makes impossible to replicate a test.

That’s why I said I don’t have an option to create a sample project. Maybe @Christian_Schmitz can tune in?

Some of those strings should be Cstrings?

Yes. Input (command) as well as output. “Z” is MBS’ marker for a Cstring, “p” is a ptr.

That’s the problem

In what way?

You are not passing CStrings

Something like this may solve it

Var exect As Cstring = "Execute"
Var funcpz As Cstring = "(p)Z"
var p As Ptr = ExtLib.Symbol(exect)
var f As New DeclareFunctionMBS(funcpz, p)

Edit: you answered while I was editing a possible solution

var para As CString = command
f.SetParameters(para)

I don’t?
Implicit conversion to String on output does work. This is not the issue.

EDIT: funcpz and exect do not need to be CStrings. DeclareFunction MBS expects Xojo strings for the definitions.

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.

Well, you said they should… Or I did not understand what you said.