linux编译 __stdcall,Linux中是否有STDCALL?
stdcall不只是一个调用约定;除了作为调用约定之外,它还允许C和C++对象之间的同构。这里有一个例子:
#define _CRT_SECURE_NO_WARNINGS // disable marking use of strcpy as error.
#include
#include
#include
class ICdeclGreeter {
public:
virtual ~ICdeclGreeter(){}
virtual void setGreeting(const char *greeting) = 0;
virtual void greet() = 0;
};
class IStdcallGreeter {
public:
virtual __stdcall ~IStdcallGreeter(){}
virtual void __stdcall setGreeting(const char *greeting) = 0;
virtual void __stdcall greet() = 0;
};
class CdeclGreeter : public ICdeclGreeter {
public:
char *greeting;
~CdeclGreeter() {
if (greeting != nullptr) {
free(greeting);
puts("[CdeclGreeter] destroyed");
}
}
void setGreeting(const char *greeting) {
this->greeting = (char *)malloc(strlen(greeting) + 1);
strcpy(this->greeting, greeting);
}
void greet() {
puts(greeting);
}
};
class StdcallGreeter : public IStdcallGreeter {
public:
char *greeting;
__stdcall ~StdcallGreeter() {
if (greeting != nullptr) {
free(greeting);
puts("[StdcallGreeter] destroyed");
}
}
void __stdcall setGreeting(const char *greeting) {
this->greeting = (char *)malloc(strlen(greeting) + 1);
strcpy(this->greeting, greeting);
}
void __stdcall greet() {
puts(greeting);
}
};
typedef struct pureC_StdcallGreeter pureC_StdcallGreeter;
typedef struct pureC_StdcallGreeterVtbl {
void (__stdcall *dtor)(pureC_StdcallGreeter *This);
void (__stdcall *setGreeting)(pureC_StdcallGreeter *This, const char *greeting);
void (__stdcall *greet)(pureC_StdcallGreeter *This);
} pureC_IStdcallGreeterVtbl;
struct pureC_StdcallGreeter {
pureC_IStdcallGreeterVtbl *lpVtbl;
char *greeting;
int length;
};
/* naive attempt at porting a c++ class to C;
on x86, thiscall passes This via ecx register rather than
first argument; this register cannot be accessed in C without
inline assembly or calling a reinterpretation of byte array
as a function. there is no "This" argument in any of below. */
typedef struct pureC_CdeclGreeter pureC_CdeclGreeter;
typedef struct pureC_CdeclGreeterVtbl {
void (*dtor)(pureC_CdeclGreeter *This);
void (*setGreeting)(pureC_CdeclGreeter *This, const char *greeting);
void (*greet)(pureC_CdeclGreeter *This);
} pureC_CdeclGreeterVtbl;
struct pureC_CdeclGreeter {
pureC_CdeclGreeterVtbl *lpVtbl;
char *greeting;
int length;
};
void test() {
ICdeclGreeter *g = new CdeclGreeter;
g->setGreeting("hi");
g->greet();
IStdcallGreeter *g2 = new StdcallGreeter;
g2->setGreeting("hi");
g2->greet();
// we can pass pointers to our object to pure C using this interface,
// and it can still use it without doing anything to it.
pureC_StdcallGreeter *g3 = (pureC_StdcallGreeter *)g2;
g3->lpVtbl->setGreeting(g3, "hello, world!");
g3->lpVtbl->greet(g3);
g3->lpVtbl->dtor(g3);
free(g2);
/*
// cdecl passes this via ecx in x86, and not as the first argument;
// this means that this argument cannot be accessed in C without
// inline assembly or equivelent. Trying to run code below will cause a runtime error.
pureC_CdeclGreeter *g4 = (pureC_CdeclGreeter *)g;
g4->lpVtbl->setGreeting(g4, "hello, world!");
g4->lpVtbl->greet(g4);
g4->lpVtbl->dtor(g4);
free(g);
*/
delete g;
}
int main(int argc, char **argv)
{
test();
system("pause");
return 0;
}
TLDR;它不同于cdecl使得C++类在使用此约定的平台上不能从C使用,因为为了向方法发送“This”,您必须将ecx寄存器设置为“This”的地址,而不是仅仅推送它,并且同样如果你想要在C中实现一个C++可以识别的类,那么该方法需要从ecx寄存器中获取这个指针,C无法访问这个指针而没有内联装配或等效。
stdcall具有这个不错的属性,使用stdcall的类可以轻松地同时从C或C++使用,而无需对它们执行任何操作。
所以你只能#define __stdcall只要你不处理__thiscall;尽管可能还有其他一些细微的区别。
linux编译 __stdcall,Linux中是否有STDCALL?相关推荐
- spdlog linux编译出错,Linux下编写Makefile引入第三方库
Linux下编写Makefile引入第三方库 前言:一直在使用CmakaList 生成Makefile文件,其实很少去写Makefile,但是最近帮朋友处理了一个Makefile引入第三方库的问题,就 ...
- linux 编译openmp,Linux 系统中OpenMP
转自:http://hi.baidu.com/linzch/blog/item/db3252fb6227c01e6c22eb21.html *怎么在Linux上运行OpenMP程序? > 只需要 ...
- Linux编译dhcpd,linux中搭建dhcpd服务器
这一次咱们来共同看一看如何在linux中搭建dhcp服务器: 首先呢dhcp服务分为客户端IP地址动态分配服务和dhcp中继服务,小编在这里用linux系统搭建一个为客户端动态分配IP地址的dhcp服 ...
- linux编译ace,Linux下编译ACE
操作系统:Centos4.7 ACE版本:ACE-6.0.2 安装过程: 下载ACE-6.0.2.tar.gz. 下载完成后将其解压tar -zxvf ACE-6.0.2.tar.gz用户登陆目录.我 ...
- linux编译bzip2,linux bzip2 命令详解
linux bzip2 命令详解 功能说明:.bz2文件的压缩程序. 语 法:bzip2 [-cdfhkLstvVz][--repetitive-best][--repetitive-fast][- ...
- linux 编译配置文件,Linux程序源码编译安装的configure配置详解
Linux环境下,如果通过源代码编译安装程序的简单过程可以 描述为:./configure-->make-->make install.其中./configure配置脚本功能就是对你的系统 ...
- linux编译ice,linux环境下编译安装ICE
前面我们讲过了在linux环境下通过rpm的方式来安装ICE,这种安装方式可以是比较简单的,自己在安装过程中发现后面PHP无法装在IcePHP.sp模块,也有可能自己在安装过程中某个地方出错了.又尝试 ...
- linux编译sqrt,linux c sqrt
我想到的一个简单可能性是,在常见情况下,每个值保留一个压缩数组,每个值2位,而每个值分隔一个4字节(原始元素索引为24位,实际值为8位,因此(idx << 8) | value))其他的. ...
- ffmpeg arm linux编译,arm linux 移植 ffmpeg 库 + x264 + x265
背景 Ffmpeg 中带有h264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx264. ...
- linux 编译缓存,Linux磁盘缓存(disk cache)详解
在Linux系统里通过free命令,我们经常可以看到类似下面的输出: $ free -m total used free shared buffers cached Mem: 24097 21665 ...
最新文章
- 中科院德州扑克AI获卓越论文奖!AAAI 2022开奖,吴恩达获纪念讲座奖
- ## 使用MapReduce程序完成相关数据预处理
- Leetcode题库 110.平衡二叉树(递归 C实现)
- python 当前目录_virtualenvwrapper打造多版本Python环境
- vuex Payload 荷载
- PHP函数之HTMLSPECIALCHARS_DECODE
- outside of class is not definition
- 高效的css命名约定
- 洛谷OJ P3865 【模板】ST表
- HeadFirstJava——2_类与对象
- C语言大作业 商品库存管理系统
- 计算机视觉与图形学-神经渲染专题-神经体渲染:实时渲染KiloNeRF
- oracle 绑定变量语法,Delphi使用绑定变量法操作Oracle
- Cf#595 (Div. 3)D-贪心
- 国内外贵金属白银有何区别?
- TDengine 单节点Cluster not ready( 群集未就绪) 异常问题分析及解决方案
- java模拟器ios版安装失败,iOS 在模拟器上安装 Debug 调试包(.app)
- ubuntu写yacc
- 2.OrientDB连接操作
- 高级计算机职称论文自述,教师评职称自述