-->

在DotNetFx Owin 环境下调用 opencc.dll 报错

2020-11-30 17:23发布

问题:

我在netfx 4.6.2 webapi 环境下调用 opencc_convert_utf8
报错如下
An unhandled exception of type 'System.AccessViolationException' occurred in Unknown Module.
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

这是我的代码 在同版本(netfx 4.6.2)的控制台程序能运行 但是webapi不行

 public class OpenCCWrapper : IDisposable
    {
        [DllImport(@"./opencc/opencc", CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr opencc_open(string configfile);

        [DllImport(@"./opencc/opencc", CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr opencc_convert_utf8(IntPtr opencc, IntPtr input, int length);

        [DllImport(@"./opencc/opencc", CallingConvention = CallingConvention.Cdecl)]
        private static extern void opencc_convert_utf8_free(IntPtr input);

        [DllImport(@"./opencc/opencc", CallingConvention = CallingConvention.Cdecl)]
        private static extern void opencc_close(IntPtr opencc);

        private IntPtr _openCCInstance = IntPtr.Zero;

        public OpenCCWrapper(string configfilename = "s2hk")
        {
            _openCCInstance = opencc_open($@"./opencc/{configfilename}.json");
        }

        // https://stackoverflow.com/a/10773988/288936
        private IntPtr NativeUtf8FromString(string managedString)
        {
            int len = Encoding.UTF8.GetByteCount(managedString);
            byte[] buffer = new byte[len + 1];
            Encoding.UTF8.GetBytes(managedString, 0, managedString.Length, buffer, 0);
            IntPtr nativeUtf8 = Marshal.AllocHGlobal(buffer.Length);
            Marshal.Copy(buffer, 0, nativeUtf8, buffer.Length);
            return nativeUtf8;
        }

        private string StringFromNativeUtf8(IntPtr nativeUtf8)
        {
            int len = 0;
            while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
            byte[] buffer = new byte[len];
            Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
            return Encoding.UTF8.GetString(buffer);
        }

        public string Convert(string text)
        {
            IntPtr inStr = NativeUtf8FromString(text);
            IntPtr outStr = opencc_convert_utf8(_openCCInstance, inStr, -1);
            Marshal.FreeHGlobal(inStr);
            return StringFromNativeUtf8(outStr);
        }

        public void Dispose()
        {
            opencc_close(_openCCInstance);
        }
    }

回答1:

应该是IIS安全限制,改配置,尤其win32的调用很容易出这种问题。

或者 单独出去,通过进程间服务访问。



标签: opencc c# owin