2011-05-23 28 views
3

我想从我的C++程序中的dll调用纯C风格的函数。我尝试使用reinterpret_cast__cdecl来铸造函数指针,并且仍然保留_stdcall的调用约定。我是Windows C++编程的新手。在C++中使用基于C风格的堆栈调用机制来制作C函数指针

编辑代码从评论

reinterpret_cast< Error (__cdecl*)(int,int)> (GetProcAddress(Mydll::GetInstance()->ReturnDLLInstance(), "add"))(1,10) 

是我的电话。实际函数的语法似乎已经被宣布为

Error __cdecl add(int,int); 

调试抛出我的错误运行时检查失败#0。我在Windows的C++工作

+4

发表一些代码。 – 2011-05-23 22:13:13

+0

@mani通过编辑您的问题发布代码 – 2011-05-23 22:30:02

+0

@Bo和mattst88:如果我无法访问我的c代码,该怎么办?我使用getprocaddress来获取我的dll的导出函数。感谢大家的回应! @尼尔 - 我为这个笨拙的帖子感到抱歉 - 我会编辑它。 – ash 2011-05-23 22:56:25

回答

6

通常你需要使用外部的 “C” 这个......

--- c_code.h ---

void func(int arg); 
void (*func_ptr)(int arg); 

--- cpp_code。 CPP ---

extern "C" void func(int arg); 
extern "C" void (*func_ptr)(int arg); 

int main() 
{ 
    func(20); 
    *func_ptr(20); 
} 
3

这里有两件事情在工作。

第一个是调用约定。调用约定是应用程序二进制接口(ABI)的一部分,它决定调用者或被调用者是否负责清理堆栈。如果你希望你的函数正确运行,你将利用和你的DLL需要使用相同的调用约定。在WIN32 API中,这通常是__stdcall,尽管C通常使用__cdecl。

另一个问题是名称损坏。由于函数的参数构成C++中函数签名的一部分(为了实现函数重载),这些信息被合并到目标代码的符号表中。这通常是一大堆奇怪的字符。 C不需要进行名称修改,因为它不允许重载函数。

有时在C++中,你想要调用C函数(即C函数符号,而不是C++编译器)。在这种情况下,您需要在extern "C" {}块中定义该功能。

希望这会帮助你出来

+0

我的DLL函数使用__cdecl约定。我的函数指针使用same..And作为你的第二个建议,我想你说的另外两个人说了什么。但我没有用的extern我的C函数或为此事用它做任何事情的自由。没有任何其他的方式来解决它?谢谢您反应无论如何:) – ash 2011-05-23 23:41:36

+0

如果你不能编辑C头文件把extern“C”放在#include指令的周围,比如为extern“C” {\ r#包括“myCHeader.h” \ R} – doron 2011-05-24 12:59:07

+0

,由于它是令人厌烦的风险,我有一个问题。我有一个DLL,我只是使用getprocaddress和加载库来从DLL的功能。通过在extern块中封装头文件意味着什么。如果我听起来像一个新手,那就是我:D – ash 2011-05-24 17:05:52