今天遇到一个问题用C++编写一个动态链接库生成的文件为dll.dll,用在visual stdio 2010调用这个dll

调用形式:[DllImport("dll.dll")]

出现了如下问题:

对 PInvoke 函数“TestDLL!TestDLL.Program::write”的调用导致堆栈不对称。
原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。
请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
 
一开始我以为是因为函数传了指针,所以把指针改成了传整型变量,依然出现上述问题,查了网上的解决方案,
解决方案一:要在调用时加上[DllImport("dll.dll", CallingConvention = CallingConvention.Cdecl)]手册给出的意思是使用Cdecl(即调用方清理堆栈)。
解决方案二:在要生成dll的文件中,函数名前加上_stdcall,如:extern "C" __declspec(dllexport) int _stdcall write_test(int size)

两者之间的区别: WINDOWS的函数调用时需要用到栈(STACK,一种先入后出的存储结构)。当函数调用完成后,栈需要清除,这里就是问题的关键,如何清除?? 如果我们的函数使用了_cdecl,那么栈的清除工作是由调用者,用COM的术语来讲就是客户来完成的。这样带来了一个棘手的问题,不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。 如果使用__stdcall,上面的问题就解决了,函数自己解决清除工作。所以,在跨(开发)平台的调用中,我们都使用__stdcall(虽然有时是以WINAPI的样子出现)。那么为什么还需要_cdecl呢?当我们遇到这样的函数如fprintf()它的参数是可变的,不定长的,被调用者事先无法知道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用_cdecl。到这里我们有一个结论,如果你的程序中没有涉及可变参数,最好使用__stdcall关键字。

而__cdecl是C/C++和MFC程序默认使用的调用约定。

_stdcall 和 _cdecl的更多相关文章

  1. _stdcall与_cdecl(了解)

    调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议.这种协议规定了该语言的函数中的参数传送方式.参数是否可变和由谁来处理堆栈等问题.不同的语言定义了不 ...

  2. _stdcall与_cdecl

    _cdecl(C Declaration的缩写)是C/C++和MFC程序默认使用的调用约定,因此可以省略,也可以在函数声明时加上_cdecl关键字来手工指定.采用_cdecl约定时,函数参数按照从右到 ...

  3. 转:函数调用的区别:_cdecl以及_stdcall

    函数调用的几个概念:_stdcall,_cdecl.... 1._stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将 ...

  4. __cdecl 、__fastcall、__stdcall

    调用约定: __cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数 ...

  5. _fastcall

    * 1楼 __fastcall具体含义 在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就 ...

  6. __cdecl __stdcall __fastcall之函数调用约定讲解

    首先讲解一下栈帧的概念: 从逻辑上讲,栈帧就是一个函数执行的环境:函数参数.函数的局部变量.函数执行完后返回到哪里等等. 实现上有硬件方式和软件方式(有些体系不支持硬件栈) 首先应该明白,栈是从高地址 ...

  7. Linux--变量与虚拟内存

    定义一个变量:存储类型  数据类型  变量名 存储类型(变量存储的位置):auto.register.static.extern 1.auto:对于局部变量,atuo可以缺省.位置:栈 2.exter ...

  8. VC内存溢出一例 –- 调用约定不一致 (_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE)

    VC (_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE) 问题记录 VC内存溢出一例 –- 调用约定不一致 (_CRT_DEBUGGER_HOOK(_CRT_DE ...

  9. C/C++:函数的编译方式与调用约定以及extern “C”的使用

    转自:https://www.cnblogs.com/qinfengxiaoyue/archive/2013/02/04/2891908.html 函数在C++编译方式与C编译方式下的主要不同在于:由 ...

随机推荐

  1. 根据拼音首字母进行过滤的combobox

    keywords: 拼音 首字母 过滤 在combobox中输入汉字拼音的首字母时,下面列出对应的可选项,就像下面这样 1. 首先在数据库中需要设计一个表,专门用来存放药物及对应的拼音首字母,这样当用 ...

  2. 【转】Android中通知的提示音、震动和LED灯效果小例子

    通知(Notification)是 Android 系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现.发出一条通知后,手机最上方 ...

  3. Spark项目之电商用户行为分析大数据平台之(一)项目介绍

    一.项目概述 本项目主要用于互联网电商企业中,使用Spark技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行为.购物行为.广告点击行为等)进行复杂的分析.用统计分析出来的数据,辅助公司中 ...

  4. 关于checkbox自动选中

    checkbox是比较常用的,无论是权限管理还是博客的文章的标签类型的勾选,或者是上下级部门及其公司,都会用的到的. 今天主要讲的是checkbox自动根据值选中. 可参考我之前的文章:checkbo ...

  5. Android Environment 获取各种路径的方法

    <pre name="code" class="java">package com.deepoon.beyond.environment; impo ...

  6. Kubernetes1.91(K8s)安装部署过程(三)--创建高可用etcd集群

    这里的etcd集群复用我们测试的3个节点,3个node都要安装并启动,注意修改配置文件 1.TLS认证文件分发:etcd集群认证用,除了本机有,分发到其他node节点 scp ca.pem kuber ...

  7. jQueryMobile的按钮样式

    好吧,已经学了jQueryMobile一年了,今天心血来潮,想要写一篇关于jQueryMobile的博客文章,记得去年暑假在公司实习jQueryMobile,想一想真是怀念当时还是菜鸟的自己,年轻就是 ...

  8. css样式显示省略号

     用css样式显示省略号,记 .xx{ display: block; width:200px;/*对宽度的定义,根据情况修改*/ overflow: hidden; white-space: n ...

  9. [SDOI2009]HH的项链 BZOJ1878

    分析: 听说是莫队裸题,很显然,我并不喜欢莫队. 我们可以考虑将询问离线,以右端点排序,之后从1枚举到n,依次树状数组中修改i和last[i],之后当i==询问的右节点时,find一下答案就可以了. ...

  10. 2017-2018-2 20155234『网络对抗技术』Exp5:MSF基础应用

    攻击MS08-067安全漏洞--WindowsXP 在kali输入msfconsole进入控制台,依次输入指令 第一次很遗憾失败了 发现是防火墙没关重新来过成功 攻击MS11-050安全漏洞--IE7 ...