标签: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. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。