Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should CS_OUT std::string work? #263

Open
tomspilman opened this issue May 20, 2014 · 6 comments
Open

Should CS_OUT std::string work? #263

tomspilman opened this issue May 20, 2014 · 6 comments

Comments

@tomspilman
Copy link
Member

I just tried to do this...

void MyFunction(CS_OUT std::string &outString);

... it results in the following binding with an error:

public void MyFunction(out Std.String outString)
{
   var arg0 = new Std.String();
   Internal.MyFunction_0(arg0); // ERROR: cannot convert from 'Std.String' to 'System.IntPtr'
   outString = arg0;
}

That seems like it should be supported.

Is the bug in the the Std.String implementation not having a System.IntPtr cast?

Second question... why not have it generate the function with string instead and only use Std.String for the conversion? Like this...

public void MyFunction(out string outString)
{
   var arg0 = new Std.String();
   Internal.MyFunction_0(arg0);
   outString = arg0;
}
@tomspilman
Copy link
Member Author

@tritao - If you can point me in the right direction on this I can spend some time and submit a PR to implement it. Just looking for some guidance on how this should work.

@tritao
Copy link
Collaborator

tritao commented May 21, 2014

Have you tested regular Std.String bindings in C#?

The Std.String type is mostly a stub, they're not supported in CppSharp's C# backend (works fine in CLI though). I never made it work in a good enough way, I guess CppSharp should warn or error out if they're used in C# mode.

What I suggest is that you export a method returning a const char* from C++ and bind that instead, that's what we do for the parser bindings.

Regardless, we probably need to modify the Std.String type map code to take into account if the parameter has an out usage and generate the proper code.

@tomspilman
Copy link
Member Author

Have you tested regular Std.String bindings in C#?

I haven't. Mostly because it already does a fine job with const char* to System.String.

I'll give it a shot and report back.

CppSharp should warn or error out if they're used in C# mode.

Oh... so they were not intended to work outside of C++ CLI. I didn't know that at all.

What I suggest is that you export a method returning
a const char* from C++ and bind that instead, that's
what we do for the parser bindings.

I wish it was that easy. In this case it is a static API that copies string data into a buffer provided by the caller.

we probably need to modify the Std.String type map code
to take into account if the parameter has an out usage and
generate the proper code.

I'll first see if I can first setup the correct mapping manually and then look to make it work automatically.

@tomspilman
Copy link
Member Author

Have you tested regular Std.String bindings in C#?

So they don't work at all.... not that I needed them really. My issue was just one of out parameters with non-const string data, out Std.String seemed like a possible solution if it had worked.

look to make it work automatically.

So I tired for a bit to make Std.String and Std.Vector work, but gave up on it. It is very complex and I didn't have the time to battle thru it.

I went ahead and made my API use a class instance which could then hold the temporary memory needed to have non-const return strings. This solved the issue for now.

@jmoutray
Copy link

Is this not working 10 years later (2024)? My code-generated method looks like this:

        public bool ExamineVariable(string variableName, ref string value, ref string response)
        {
            var __basicString0 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
            global::Std.BasicStringExtensions.Assign(__basicString0, variableName);
            var __arg0 = __basicString0.__Instance;
            var __basicString1 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
            global::Std.BasicStringExtensions.Assign(__basicString1, value);
            var __arg1 = __basicString1.__Instance;
            var __basicString2 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
            global::Std.BasicStringExtensions.Assign(__basicString2, response);
            var __arg2 = __basicString2.__Instance;
            var ___ret = __Internal.ExamineVariable(__Instance, __arg0, __arg1, __arg2);
            value = global::Std.BasicStringExtensions.Data(__basicString1);  // Added this line to code-generated file
            response = global::Std.BasicStringExtensions.Data(__basicString2);  // Added this line to code-generated file
            __basicString0.Dispose();
            __basicString1.Dispose();
            __basicString2.Dispose();
            return ___ret;
        }

I had to add the lines above (with the //Added this line... comment)` in order for the variables to get assigned.

Is there something I can do to generate this file correctly (with the lines added) or is this functionality still not implemented?

@tritao
Copy link
Collaborator

tritao commented May 14, 2024

Is this not working 10 years later (2024)? My code-generated method looks like this:

        public bool ExamineVariable(string variableName, ref string value, ref string response)
        {
            var __basicString0 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
            global::Std.BasicStringExtensions.Assign(__basicString0, variableName);
            var __arg0 = __basicString0.__Instance;
            var __basicString1 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
            global::Std.BasicStringExtensions.Assign(__basicString1, value);
            var __arg1 = __basicString1.__Instance;
            var __basicString2 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
            global::Std.BasicStringExtensions.Assign(__basicString2, response);
            var __arg2 = __basicString2.__Instance;
            var ___ret = __Internal.ExamineVariable(__Instance, __arg0, __arg1, __arg2);
            value = global::Std.BasicStringExtensions.Data(__basicString1);  // Added this line to code-generated file
            response = global::Std.BasicStringExtensions.Data(__basicString2);  // Added this line to code-generated file
            __basicString0.Dispose();
            __basicString1.Dispose();
            __basicString2.Dispose();
            return ___ret;
        }

I had to add the lines above (with the //Added this line... comment)` in order for the variables to get assigned.

Is there something I can do to generate this file correctly (with the lines added) or is this functionality still not implemented?

The issue is still open, so I think so, apparently no one has cared enough to look into it and send a PR.
You seem to have found the fix, which is great, can you look into adding this in the generator and send a PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants