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可以在任意指定的系统路径内.

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述