ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-08-15 00:30:28  阅读:143  来源: 互联网

标签:pArg IntPtr S1C1 int dll FB CallingConvention PInvoke Foo


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有