Compiling for netcore targeting Linux (Ubuntu)

Jason Daly <[email protected]>
Newsgroups gmane.comp.programming.swig
Message-ID <CAO3BKArPJygzqc24qhs5gMC=X3+4oWmBP2UBkK6C61hkoqByLw@mail.gmail.com>
Hi,
We are using SWIG to wrap some C++ libraries with C#, and compiling the
wrapper code in an aspnetcore service, which runs in a Docker container,
targeting Linux. So, .net, running on Linux, calling in to some native
linux .so libs.

We have been having problems with string marshalling.
Ubuntu uses 32-bit chars, and the libs we are wrapping make use of the
std::wstring type.

We had to implement a custom marshaller for marshalling the C# strings
to/from std::wstring using UTF32 encoding (see below).

Then we had to swap out the SWIG std_wstring.i script with our own custom
one for ubuntu, which uses our custom marshaller.

We still have one more issue to resolve - the
generated SWIGWStringHelper's, CreateWString method incorrectly marshalls
strings using LPWStr. We need this to use our custom UTF32 marshalling.

I think what I need to do is write my own SWIGWStringHelper, and decorate
CreateWString to use my UTF32 marshaller. But I am not sure how to 'wire
this in'.

Please advise.

Also, I am wondering if the SWIG .NET contributors are doing any work to
better support this case (netcore apps, interoperating with Linex .so libs,
running on Ubuntu or equivalent Docker containers)?

Regards,
Jason Daly

    public class UTC32StringMarshaller : ICustomMarshaler
    {
        static UTC32StringMarshaller singleton;

        public IntPtr MarshalManagedToNative(object managedObj)
        {
            if (managedObj == null)
                return IntPtr.Zero;
            if (!(managedObj is string))
                throw new MarshalDirectiveException("UTC32StringMarshaller
must be used on a string.");

            var nullTerminated =
$"{(string)managedObj}{Convert.ToChar(0x0).ToString()}";
            byte[] strbuf = Encoding.UTF32.GetBytes(nullTerminated);
            IntPtr buffer = Marshal.AllocHGlobal(strbuf.Length);
            Marshal.Copy(strbuf, 0, buffer, strbuf.Length);
            return buffer;
        }

        public unsafe object MarshalNativeToManaged(IntPtr pNativeData)
        {
            int pos = 0;
            while (Marshal.ReadInt32(pNativeData, pos) != 0)
                pos += 4;

            byte[] strbuf = new byte[pos];
            Marshal.Copy((IntPtr)pNativeData, strbuf, 0, pos);
            return Encoding.UTF32.GetString(strbuf);
        }

        public void CleanUpNativeData(IntPtr pNativeData)
        {
            Marshal.FreeHGlobal(pNativeData);
        }

        public void CleanUpManagedData(object managedObj)
        {
        }

        public int GetNativeDataSize()
        {
            return -1;
        }

        public static ICustomMarshaler GetInstance(string cookie)
        {
            if (singleton == null)
                return singleton = new UTC32StringMarshaller();

            return singleton;
        }
    }

_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.