其他分享
首页 > 其他分享> > FB(S1C1): PInvokeStackImbalance对PInvoke函数的调用导致堆栈不对称

FB(S1C1): PInvokeStackImbalance对PInvoke函数的调用导致堆栈不对称

作者:互联网

FB(S1C1): PInvokeStackImbalance对PInvoke函数的调用导致堆栈不对称

 

问题:

    C#语言 对 C语言 导出函数进行调用时报出的错误.

 方案:

    设置调用约定CallingConvention的枚举值中的CallingConvention.Cdecl.

 实施:

    C语言导出函数形式

   extern "C" __declspec(dllexport) int Foo(char* pArg);

    C#语言调用形式之一

[DllImport("Foo.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int Foo(IntPtr pArg);

        注:

            上述Foo.dll在操作系统环境搜索路径内.

 

    C#语言调用形式之二

          

           1.声明相关加载动态库和获取调用函数

               /// <summary>
               /// a.加载动态库
               /// </summary>
               [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", CallingConvention = CallingConvention.StdCall)]
               static extern IntPtr LoadLibrary(string strFileName);
               
               /// <summary>
               /// b.获取动态库中函数指针
               /// </summary>
               [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi)]
               static extern IntPtr GetProcAddress(IntPtr pModule, string strFuncName);
               
               /// <summary>
               /// c.释放动态库
               /// </summary>
               [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", CallingConvention = CallingConvention.StdCall)]
               static extern int FreeLibrary(IntPtr pModule);
           2.声明调用指定函数的委托               
               [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
               delegate int Foo(IntPtr pArg);
           3.使用上述声明函数及委托               
                void FooCall()
                {
                    //1
                    IntPtr pFooDLL = LoadLibrary("Foo.dll");
                    if (IntPtr.Zero != pFooDLL)
                    {
                        //2
                        IntPtr pFoo = GetProcAddress(pFooDLL, nameof(Foo));
                        if (IntPtr.Zero != pFoo)
                        {
                            //Foo
                            Foo funcFoo = (Foo)Marshal.GetDelegateForFunctionPointer(pFoo, typeof(Foo));
                            if (null != funcFoo)
                            {
                                IntPtr pArg = Marshal.StringToCoTaskMemAnsi("Args");
                                int iReturn = funcFoo(pArg);
                            }
                        }

                        //3
                        FreeLibrary(pFooDLL);
                    }
                }
注:

               上述Foo.dll可以在任意指定的系统路径内.

标签:pArg,IntPtr,S1C1,int,dll,FB,CallingConvention,PInvoke,Foo
来源: https://www.cnblogs.com/wjshan0808/p/16586813.html