StringBuilder marshalling length limit on windows (bug?)

This might be a bit of a niche but I have a problem (bug?) and I’m trying to pre-empt it a bit etc.

I’m sending a char* buffer to a c/++ plugin with a StringBuilder, then modifying it’s contents and returning. This is working fine in Android, IOS and OSX. In Windows, if the size of the StringBuilder is too large, I get a valid char* buffer passed to c/++ but when I modify the contents it’s not reflected in c#. If I put a string in it before calling my c/++ function it’s still there. If I add nothing, it’s still got nothing in it.
I’m not getting any warnings or errors and the size limit varies (at one point it was 641, then 330).
I can detect the “failure” as I return the string length from my function and if the StringBuilder.toString() length is 0 I know my changes haven’t been made and can retry with a smaller buffersize. But I really want to avoid this.

This is the marshalling I’ve been using c# side

    [DllImport (PluginName, CallingConvention=CallingConvention.Cdecl)]
    private static extern int       PopMovie_EnumSources(StringBuilder Buffer,uint BufferSize,string IncludeFilter,string ExcludeFilter,string Directory0,string Directory1,string Directory2,string Directory3);

(I’ve tried changing the calling convention to std, setting the ansi charSet, adding marshall type to StringBuffer, but they make no difference)

and c

extern "C" __declspec(dllexport)Unity::sint    PopMovie_EnumSources(char* Buffer,Unity::uint BufferSize,const char* IncludeFilter,const char* ExcludeFilter,const char* Directory0,const char* Directory1,const char* Directory2,const char* Directory3);

Does anyone know how I can detect if I’ve got a buffer that is essentially read only?
or if this is a known issue, or some inherit problem of marshalling or string builder?

I can kind of work around it, but without knowing exactly what’s going wrong, even my workarounds might not be without fault.

1 Like

Nope. This method was too unreliable for me doing cross platform work.

I ditched it all for an API which returns a char* which I use as a string, then tell my API to release it when done