Buoy questions

  • docs/documentation/namespaces.md:75 — “Classes and enums inside Namespace blocks are not yet supported; only Function and Sub declarations are valid inside a Namespace body.”

@einhugur - tonight’s build has some changes that should help with your library experiments.

Those here are the new search paths:

They look good, the last 2 are relative to the project file.
Only thing I am wondering about is should they have platform directories maybe ?

Other thing unrelated that I am a little worried about… So if I am returning string from the library that has no persistent backing then I am having to call back into the library to have it disposed after I return it to Buoy, which is a little difficult to say the least to manage. I wonder if eventually some sort of SDK would be needed so that it could simply return a Buyo string that Buyo manages then with its reference counting. I don’t even know if this is possible, depends on your core design I guess.

I wrote to quick

Using the 2nd last of the paths for it… /Users/Shared/Git/Buoy Components/Word/Test/libWord.dylib

Gives me this:

Edit: I got that one resolved it was the rpath thing.

just like with Xojo, if you’re going to be declaring directly into a library of some sort, retention of items needs to be handled by the caller. But to be fair, that’s for objects.

Did you look at the included docs and examples about packaging and declares?

Yes I looked. (hopefully well enough)

Its a generic problem usually with declares though if the Library is just returning char that is generated on the fly then simple char* struct does not handle it well. Since you would need to come back to delete it. (unless there is a way to tell the declare to own the pointer)

As far as I can see the documentation only says:

String return values from C are assumed to be null-terminated and are copied into a Buoy String.

So if a library is returning string there that it generated on the fly then it will have no place to delete it, since it returns it to Buoy and Buoy makes a copy of it. But the library has no chance to delete it because you have returned from the function.

And adding here a bug (going from one subject to another, I know its shameless of me)

(Could not get the forum to make it look sane so putting it as picture)

Basically here the Destructor on Class2 will never get called.

I only included the creation via the Shared function since I thought that was maybe the problem at first. But it fails in both cases, only destructor on Class1 gets called.

Please file that bug on the releases repository.

For your “release” question:

c++

#include <cstring>
#include <cstdlib>

// Allocates a buffer the CALLER must free.
extern "C" char *make_greeting(const char *name) {
    const char *prefix = "Hello, ";
    size_t len = std::strlen(prefix) + std::strlen(name) + 1;
    char *buf = static_cast<char *>(std::malloc(len));
    std::strcpy(buf, prefix);
    std::strcat(buf, name);
    return buf;                 // ownership transfers to Buoy
}

// The matching deallocator Buoy will call.
extern "C" void free_cstr(char *p) {
    std::free(p);
}

Buoy

' Return the allocation as a Ptr — NOT As String — so Buoy doesn't
' silently copy-and-leak it.
Declare Function MakeGreeting Lib "greet" Alias "make_greeting" (name As String) As Ptr
Declare Sub      FreeCStr     Lib "greet" Alias "free_cstr"      (p As Ptr)

Sub Main()
    Dim raw As Ptr = MakeGreeting("Björn")    ' C malloc's a char* and hands us ownership
    Dim text As String = CType(raw, String)  ' copy the NUL-terminated UTF-8 into a Buoy String
    FreeCStr(raw)                             ' release the C buffer now that we've copied it
    Print text                               ' Hello, Greg
End Sub

We’re not quite ready for plugin development.

That was sort of why I was hinting at maybe at some point we need some sort of SDK to some things to avoid those copying and allocations and de allocations just to move string.

(in the future of course, am not trying to rush you for such things !)

I already can do a lot which is awesome, I even managed to get this here to work today:

That Writes a Word document.

(of course I only have few routines of it out of hundreds but still shows that it can be done to make some components )

The advised CType way does not seem to be good, the print there that I use is good, the text I return is garbage. So it goes garbage after the free. So is a bit like the CType is maybe not copying ?

I basically print it out again in the caller of the property after the return and at that point its garbage.

There will be an SDK to make all of this easier at some point but in the mean time there are bigger issues to fix.

No worries, no issue there and no rush, you are doing awesome.

Note that the picture I posted above I think is a bug maybe if the CType is supposed to be copying.

Interesting question

As far as I recall in Xojo it more like a “reinterpret cast” so no copying

However, that doesn’t mean that has to be the case in Buoy

I’m pretty sure that’s what’s going on here too.

Björn,

I noticed in your screenshot that your code is:

var s = Type(p, String)

whereas the code I posted is:

var s as String = Type(p, String)

I’m betting that the type inference stuff doesn’t work with CType. Can you try that?

Thanks for the suggestion.

Sadly it did not solve it though. I get good value from S, but S becomes Garbage after the dispose. Same as before.

To simplify the test then I now print out the value before and after the test instead of returning and then printing again.

This will print out:

Got text pointer: Hello World
Got text pointer: �

I guess I’ll have to peek at the SQLite package because I’m pretty sure this is working and it doesn’t leak.

What is the fastest / best way to convert Boolean to Int8 to use in API.

The CType did not work, direct cast did not work, and In line if is either not supported or I do not know the syntax for it I guess.

I of course can do if then else if needed. Am just curious if there is better way so I don’t put bad way of doing things all over.

Thanks

Can you pass the Boolean directly to the declare?

No that gives me type mismatch

/Users/Shared/Git/Buoy Components/Word/Test/word.bui:153:0: error: argument 2 type mismatch: expected Int8, got Boolean

I installed Buoy, along with its extension for VS Code, and set my PATH to its directory. However, when I tried to run one of the sample programs using VS Code’s Run Without Debugging command, I got the following error message:

Buoy: build failed – spawn
/Applications/Develop/BASIC/Buoy EACCES
Source: Buoy

What am I doing wrong?