Closed jannikov closed 5 years ago
libdigidocpp API requires input to be UTF-8 encoding. Not ANSI local
Yes, I have input in UTF8. but anyway I got error
57 line does not make any sense. Converting from utf-8 to utf-8? And some places is variable file and some filename? Whats the difference
it only for example. To explain. And .net returned, that this file is exist
I changed the names. One filename is BDOC container and another one is file that should be signed
Maybe there is some trick with codepage? I already double checked, I have UTF 8
And why you are doing filename conversions if you expect it in the utf8. \libdigidocpp\source\src\util\File.cpp Check fileExists -> encodeName -> convertUTF8
Because we need to have cross platform similar API. It Encodes input (UTF-8) to Windows Wide character API.
Seems like PINVOKE resolves parameters to local ANSI encoding. This needs more investigating
Thank you! Yes I tried to to change charset in the PINVOKE generated code. But there are only Unicode and ANSI options available. And no success because Unicode it have more bytes then UTF-8. At the moment I trying to find some workaround.
[global::System.Runtime.InteropServices.DllImport("digidoc_csharp", EntryPoint="CSharp_digidoc_Container_addDataFile", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] public static extern void Container_addDataFile(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, string jarg3);
One thing else. SWIG generated only one addDataFile method, the second addDataFile with steam argument is missing. I think it because they both having same name.
Thank you! Yes I tried to to change charset in the PINVOKE generated code. But there are only Unicode and ANSI options available. And no success because Unicode it have more bytes then UTF-8. At the moment I trying to find some workaround.
[global::System.Runtime.InteropServices.DllImport("digidoc_csharp", EntryPoint="CSharp_digidoc_Container_addDataFile", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] public static extern void Container_addDataFile(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, string jarg3);
Unicode maps to Wide character set. There are couple feature requests https://github.com/dotnet/corefx/issues/7804 https://github.com/dotnet/coreclr/issues/1012 Right now we need solve this in swig generated wrapper somehow
One thing else. SWIG generated only one addDataFile method, the second addDataFile with steam argument is missing. I think it because they both having same name.
Swig does not have c++ stream and C# stream mappings support right now
SWIG even generates some wrapper for istream. But I dont't know how to map it
public virtual void bbb(SWIGTYPE_p_std__istream arg0, string fileName, string mediaType) { digidocPINVOKE.Container_bbb(swigCPtr, SWIGTYPE_p_std__istream.getCPtr(arg0), fileName, mediaType); if (digidocPINVOKE.SWIGPendingException.Pending) throw digidocPINVOKE.SWIGPendingException.Retrieve(); }
global::System.Runtime.InteropServices.DllImport("digidoc_csharp", EntryPoint="CSharp_digidoc_Container_bbb")]
public static extern void Container_bbb(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, string jarg3, string jarg4);
`
SWIG even generates some wrapper for istream.
public virtual void bbb(SWIGTYPE_p_std__istream arg0, string fileName, string mediaType) { digidocPINVOKE.Container_bbb(swigCPtr, SWIGTYPE_p_std__istream.getCPtr(arg0), fileName, mediaType); if (digidocPINVOKE.SWIGPendingException.Pending) throw digidocPINVOKE.SWIGPendingException.Retrieve(); }
global::System.Runtime.InteropServices.DllImport("digidoc_csharp", EntryPoint="CSharp_digidoc_Container_bbb")] public static extern void Container_bbb(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, string jarg3, string jarg4); `
This is not usable in C# Here is list c++ std supported types https://github.com/swig/swig/tree/master/Lib/csharp
Heia, I found workaround. Has been added 2 new methods and modified PINVOKE proxy. See code bellow, hope this code will be helpfull to you.
Container.cpp
Container* Container::createWin(wchar_t *path) { string pathDecoded = util::File::decodeName(path); return create(pathDecoded.c_str()); }
Container.cs
public static Container createWin(string path) { global::System.IntPtr cPtr = digidocPINVOKE.Container_createWin(path); Container ret = (cPtr == global::System.IntPtr.Zero) ? null : new Container(cPtr, false); if (digidocPINVOKE.SWIGPendingException.Pending) throw digidocPINVOKE.SWIGPendingException.Retrieve(); return ret; }
public virtual void addDataFileWin(string path, string mediaType) { digidocPINVOKE.Container_addDataFileWin(swigCPtr, path, mediaType); if (digidocPINVOKE.SWIGPendingException.Pending) throw digidocPINVOKE.SWIGPendingException.Retrieve(); }
ASiContainer.cpp
void ASiContainer::addDataFileWin(wchar_t *path, wchar_t *mediaType) { string pathDecoded = File::decodeName(path); string mediaTypeDecoded = File::decodeName(mediaType); addDataFile(pathDecoded.c_str(), mediaTypeDecoded.c_str()); }
digidocPINVOKE.cs
[global::System.Runtime.InteropServices.DllImport("digidoc_csharp", EntryPoint = "CSharp_digidoc_Container_createWin", CharSet = System.Runtime.InteropServices.CharSet.Unicode, CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] public static extern global::System.IntPtr Container_createWin(string jarg1);
[global::System.Runtime.InteropServices.DllImport("digidoc_csharp", EntryPoint= "CSharp_digidoc_Container_addDataFileWin", CharSet = System.Runtime.InteropServices.CharSet.Unicode, CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] public static extern void Container_addDataFileWin(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, string jarg3);
Can you test https://ci.appveyor.com/project/open-eid/libdigidocpp/builds/21722020/job/xyc9cyf3879401vn/artifacts if build completes
Yes UTF8Marshaler works!
I have libdigidocpp-3.13.8.1379 installed on windows 10