vc++-VC++、DLL、虚函数、调用约定

问题描述

VC++、DLL、虚函数、调用约定
关于“VC++、DLL、虚函数、调用约定”的一个问题折腾我很久了,希望CSDN的朋友可以助我解决问题。

DLL里,接口类的虚函数(非纯虚函数),应该怎样调用约定?


背景描述:
一个DLL工程A(接口),有个接口类AI,里面全是纯虚函数。
一个EXE工程B(平台),有个成员变量mc类型是类AI。
一个DLL工程C(游戏),有个类是类AI的子类,即实现类,对类AI的所有接口(纯虚函数)进行了实现。

原理是:
平台只有一个在跑,而游戏是N个,工程B(平台)的mc被赋值成工程C(游戏)的对象,通过工程A的接口,mc可以调用工程C(游戏)里的函数(接口的实现)。

问题:
我在开发一个新游戏时,发现工程A(接口)类AI的接口不够用,想新增一个接口,于是加入了一个”虚函数“,注意不是“纯虚函数”,为的是不影响之前所有已有的游戏(不然之前的游戏不作任何改动而编译 会报error C2259: 不能实例化抽象类),即之前的游戏不用实现这个接口,修改工程B(平台)调用这个函数时是工程A(接口)新增的接口,若游戏实现这个接口,就调用游戏里的实现函数;若游戏没有定义这个接口(之前的游戏),则调用工程A(接口)类AI里的虚函数(里面只有一句调试打印)。

但发现,有的游戏是正常的,有的游戏不正常。不正常的游戏,调试工程B(平台)在调用新接口时提示:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

百度了一下,很多人说是调名约定的问题。
工程A、工程B、所有的游戏工程C,工程选项里都是 __cdecl (/Gd)。

于是我在工程A、工程C里下面几种尝试:
virtual void OnEventABC(int a bool b); //没写调用约定,有的游戏正常,有的游戏出错
virtual void __stdcall OnEventABC(int a bool b); //所有的游戏都出错
virtual void __cdecl OnEventABC(int a bool b); //所有的游戏都出错
virtual void WINAPI OnEventABC(int a bool b); //所有的游戏都出错


请问大家,怎么解决这个问题,是调名约定的问题,还是其它什么问题?

解决方案

问题已解决,谢谢大家的无语让我自己解决了。

解决方案二:
你没有传this指针,导致堆栈不平衡。

解决方案三:
请问工程A、C如何写,工程B里调用如何写?

时间: 2024-10-30 12:15:42

vc++-VC++、DLL、虚函数、调用约定的相关文章

带你玩转Visual Studio——调用约定与(动态)库

上一篇文章带你玩转Visual Studio--调用约定__cdecl.__stdcall和__fastcall中已经讲述了__cdecl.__stdcall和__fastcall几种调用约定的主要区别.这一章将进一步深入了解不同调用约定对编译后函数修饰名的影响,及调用约定对库函数的影响. VS设置默认的调用约定 上一章已经讲了,C/C++默认的调用约定是__cdecl,那能不能修改这个默认的调用约定呢?答案是肯定的.假设你有一个工程名叫VisualStudio,你想让这个工程下的所有函数默认都

实例讲解C++编程中的虚函数与虚基类_C 语言

虚函数① #include "stdafx.h" #include <iostream> using namespace std; class B0//基类B0声明 { public: void display(){cout<<"B0::display()"<<endl;}//公有成员函数 }; class B1: public B0//公有派生类B1声明 { public: void display(){cout<<

vc++-VC6如何在生成动态链结库的文件(DLL)里调用SQL2000

问题描述 VC6如何在生成动态链结库的文件(DLL)里调用SQL2000 VC6如何在生成动态链接库的文件(DLL)里调用SQL2000,最终该文件要用于VFP环境内, 也就是要在SET LIBARY TO XX.DLL里调用里的函数,该问题很是急,麻烦大侠们高抬贵 手! 解决方案 VC产生动态链接库以及调用sql server都不麻烦,只是看你vfp能不能调用了.你的具体问题是什么. 解决方案二: 生成标准windows DLL,用_stdcall调用约定来封装DLL的导出函数等. 解决方案三

vc++-VC++如何调用C#编写的串口驱动 DLL

问题描述 VC++如何调用C#编写的串口驱动 DLL 最近弄一个串口打印的项目,我一直是用VC++进行开发的,c#没用过,但是对方提供的打印机的DEMO却是C#的例程,本来想着DLL是跨语言的,应该没什么问题,但是我用vc++编写了一个测试程序,确没有任何数据输出,很简单的例程,我按流程在上面加了打开串口,设置串口,发送数据,关闭串口.这几步都是用的现成的dll里面的函数,他把串口的数据操作也封装起来了,然后我就想到,在c#中是可以直接用库函数对串口读写,是不是因为这个原因,导致我在vc++中不

dll生成-VC++生成DLL文件,产生的函数前面带下划线 后面带@符号,请问这个怎么解决?

问题描述 VC++生成DLL文件,产生的函数前面带下划线 后面带@符号,请问这个怎么解决? 如题 函数名应该是 Java_GoodLuck_get 但是结果却是这样 _Java_GoodLuck_get@8. 这样我不能用Java调用这个DLL里面的函数啊.大神求助. 解决方案 LZ可以参考这篇文章:http://blog.csdn.net/codehat/article/details/4439465 应该是你没有指定导出符号,所以就会默认生成符号,默认生成的符号里面就有些特殊字符. 解决方案

struts2 0+dll-java web项目调用 vc++的dll文件

问题描述 java web项目调用 vc++的dll文件 我用java 的jni调用vc++写好的dll动态链接库,使用main方法测试没有问题,但是放在web项目的Action中调用就不执行,在static{ System.put.println("load dll..."); System.loadlobrary("ukeyjni"); system.out.println("end load..."); } 上面的调用前后都能打印,在调用的

jnative调用VC编译DLL 返回值解析

问题描述 VC编译的DLL中函数Longrequest(stringbuf1,stringbuf2) ,其中buf1为输入参数,buf2为预先分配地址空间的变量,并将函数执行的结果存入其中.java端通过JNative组件来调用Pointerpointer=newPointer(MemoryBlockFactory.createMemoryBlock(65535));jNative.setParameter(0,pram);//入口参数jNative.setParameter(1,pointer

vc++-ocx在dll中的调用(关于vc里的mfc)

问题描述 ocx在dll中的调用(关于vc里的mfc) dll里边封装了一个对话框,现在在这个对话框里边insert activex control一个ocx控件,调用这个dll,对话框弹不出来, 若没有加入这个ocx,调用dll会弹出对话框 解决方案 很像是里面发生异常了,可以试试debugview看能抓到异常信息不.

VC++动态链接库(DLL)编程深入浅出

  4.2 声明导出函数 DLL中导出函数的声明有两种方式:一种为4.1节例子中给出的在函数声明中加上__declspec(dllexport),这里不再举例说明;另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出.属性及其他方面的信息. 下面的代码演示了怎样同.def文件将函数add声明为DLL导出函数(需在dllTest工程中添加lib.def文件): ; lib.def : 导出DLL函数 LIBRARY dllTest EXPORTS add