使用ASP.NET中的P / Invoke调用非托管DLL函数时的访问冲突异常,C#

时间:2016-07-02 08:30:38

标签: c# c++ asp.net .net

ASP.NET应用程序中出现以下错误 ,我已成功在Windows窗体应用程序中运行完全相同的代码而没有任何错误。

我无法访问库的源代码,也无法访问符号文件。它是32位&我已将我的应用程序设置为在x86中运行。

当库的功能时弹出以下错误: Error message

这是调用堆栈: Call stack

这些是DLL导入代码:

    [DllImport("encrypt32pki.dll", EntryPoint = "LIBRARYInitiateEncrypt", CallingConvention = CallingConvention.Cdecl)]
    unsafe private static extern int LPFNDLLLIBRARYINITIATEENCRYPT(string pkids, int noOfPkid, ref IntPtr errorArr, ref LIBRARYBlob LIBRARYBlob, string currUser);

    [DllImport("encrypt32pki.dll", EntryPoint = "LIBRARYDoEncrypt", CallingConvention = CallingConvention.Cdecl)]
    unsafe private static extern int LPFNDLLLIBRARYDOENCRYPT(string pkids, string inputfullpath, string inputfilename, string outputfullpathfilename, int noOfPkid, ref IntPtr errorArr, ref LIBRARYBlob LIBRARYBlob, string currUser);

这些是实际分配变量以调用函数的代码:

    public unsafe int encrypt(string[] pkids, string inputfullpath, string inputfilename, string outputfullpath, string currentuser)
    {
        IntPtr errorArray = new IntPtr(0);

        LIBRARYBlob blob = new LIBRARYBlob();
        string pkid = string.Join(",", pkids);
        int pkidlen = pkids.Length;

        byte[] aes = new byte[33];

        // Original should have a size_t (if crash, maybe the following lines are culprit since size_t is 8bytes and IntPtr is also like that.)
        blob.fake1 = new IntPtr(-1);
        blob.fake2 = new IntPtr(-1);

        GCHandle pinnedAes = GCHandle.Alloc(aes, GCHandleType.Pinned);
        IntPtr pointerAes = pinnedAes.AddrOfPinnedObject();

        blob.sypAesKey = pointerAes;

        GCHandle[] gcpkid = new GCHandle[pkidlen];
        GCHandle[] gcblob = new GCHandle[pkidlen];

        byte* pkaddresses = stackalloc byte[4 * pkidlen];
        byte* blobaddresses = stackalloc byte[4 * pkidlen];

        var allocatedMemoryPkid = new List<IntPtr>();
        var allocatedMemoryBlob = new List<IntPtr>();
        IntPtr nativeArrayPkid = Marshal.AllocHGlobal(4 * pkidlen);
        IntPtr nativeArrayBlob = Marshal.AllocHGlobal(4 * pkidlen);

        for (int i = 0; i < pkidlen; i++)
        {
            IntPtr nativePkid = Marshal.AllocHGlobal(50);
            IntPtr nativeBlob = Marshal.AllocHGlobal(170);
            allocatedMemoryPkid.Add(nativePkid);
            allocatedMemoryBlob.Add(nativeBlob);
            Marshal.WriteIntPtr(nativeArrayPkid, i * 4, nativePkid);
            Marshal.WriteIntPtr(nativeArrayBlob, i * 4, nativeBlob);


        }
        blob.sypEnPkids = nativeArrayPkid;
        blob.sypBlobs = nativeArrayBlob;

        int initializeResult = 0;
        int encryptResult = 0;

        try
        {

            initializeResult = LPFNDLLLIBRARYINITIATEENCRYPT(pkid, pkidlen, ref errorArray, ref blob, currentuser);
            encryptResult = 0;
            if (initializeResult == 1)
            {
                // Ok. Do encrypt.
                encryptResult = LPFNDLLLIBRARYDOENCRYPT(pkid, inputfullpath, inputfilename, outputfullpath, pkidlen, ref errorArray, ref blob, currentuser);
                Console.WriteLine("Encrypt result = " + encryptResult);
            }
            else
            {
                Console.WriteLine("Error!" + errorArray.ToString());
            }
        }
        catch (Exception ex)
        {
            logger.Error(ex.Message);
        }

        Marshal.FreeHGlobal(errorArray);

        pinnedAes.Free();
        foreach (IntPtr ptr in allocatedMemoryPkid)
        {
            Marshal.FreeHGlobal(ptr);
        }

        foreach (IntPtr ptr in allocatedMemoryBlob)
        {
            Marshal.FreeHGlobal(ptr);
        }
        if (initializeResult == 1) return encryptResult;
        else return initializeResult;
    }

0 个答案:

没有答案