龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

C++类包含函数说明

时间:2011-04-12 23:18来源:未知 作者:admin 点击:
分享到:
C++类 包含三个我们关心的函数:构造函数,析构函数,和所有重要的 DoSomething 函数,我们需要把每一个函数包裹成与其等价的C++函数,在这里拿出来和大家分享一下。 //originalclass cl

C++类包含三个我们关心的函数:构造函数,析构函数,和所有重要的 DoSomething 函数,我们需要把每一个函数包裹成与其等价的C++函数,在这里拿出来和大家分享一下。

  1. // original class  
  2. class CFoo  
  3. {  
  4. public:  
  5.  CFoo(int x);  
  6.  ~CFoo();  
  7.  int DoSomething(int y);  
  8. };  
  9. // flattened C code  
  10. void* __stdcall new_CFoo(int x)  
  11. {  
  12.  return new CFoo(x);  
  13. }  
  14. int __stdcall CFoo_DoSomething(void* handle, int y)  
  15. {  
  16.  CFoo *foo = reinterpret_cast<CFoo *>(handle);  
  17.  return foo->DoSomething(y);  
  18. }  
  19. void __stdcall delete_CFoo(void *handle)  
  20. {  
  21.  CFoo *foo = reinterpret_cast<CFoo *>(handle);  
  22.  delete foo;  

这里有几个比较重要的地方要注意。首先,注意每一个C++类被映射为一个简单的 C 函数。其次,观察到我们为 C 函数明确地使用 __stdcall 调用习惯。在前一篇 DLL 文章里,我们知道简单的调用在 MSVC DLL 里的无格式 C 函数,真是很麻烦。

如果我们放弃越过种种艰难困苦去用它,我们可以使这个努力稍微容易一点。让 Borland 调用 Microsoft DLL 最简单的办法是 DLL 导出无格式,无修饰,__stdcall 调用习惯的 C++函数。Borland 和 Microsoft 对 __cdecl 函数的处理上是不同的。

通常,他们对 __stdcall 函数也不同,因为 MSVC 修饰 __stdcall 函数,但我们可以通过添加一个 DEF 文件到 MSVC 工程里来阻止这种行为。参见下载部分的例子有 DEF 文件的例子。其它关于代码要注意的事情是 new_CFoo 函数返回一个指向 CFoo 对象的指针。BCB 调用者必须在本地保存这个指针。这可能看起来和这篇文章的主题有点矛盾。

毕竟,我想 BCB 不能使用来自 MSVC DLL 的 C++?如果那是正确的,那么为什么我们还要返回一个 CFoo 对象指针呢?答案是 BCB 不能调用 MSVC DLL 导出类的成员函数。但是,这并不意味着它不能存储这样对象的地址。new_CFoo 返回的是一个 CFoo 对象的指针。

BCB 客户端可以存储这个指针,但不能用。BCB 不能废弃它(不应当尝试这么做)。让这个观点更容易理解一点,new_CFoo 返回一个空指针(总之它不能返回别的什么东西)。在 BCB 这边,除了存储它,然后把它传回给 DLL,没有什么可以安全地处理这个空指针的方法。

Ok,在我们继续前进之前,还有另外两个要十分注意的地方。首先,注意 CFoo_DoSomething 把空指针作为它的第一个参数这个空指针与 new_CFoo 返回的是同一个空指针。空指针用 reinterpret_cast 被追溯到 CFoo 对象(你知道,当你看到一个 reinterpret_cast 的时候。

你正在处理是难看的代码)。DoSomething 成员函数在转换之后被调用。最后注意空指针也是C++的参数。包装 DLL 删除对象是至关紧要的。你不应当在 BCB 里对空指针调用 delete。显然它不会按你想的去做。

精彩图集

赞助商链接