错误C2040:'MyClass':'void *'与'MyClass'的间接级别不同

时间:2015-09-17 05:51:02

标签: c++

我写了一个DLL(C ++)的C_Wrapper。 头文件

#define DLLIMPORT __declspec (dllexport)
#ifdef __cplusplus
extern "C" { 
#endif
typedef void* MyClass;
DLLIMPORT MyClass* createWrapper(double a, double b);
#ifdef __cplusplus
}
#endif

源文件:

#include "stdafx.h"
#include "MyClass.h"
#include "C_DllWrapper.h"

DLLIMPORT MyClass* createWrapper(double a, double b)
{
   return new MyClass(a,b); 
}

我收到以下错误消息: 错误C2040:'MyClass':'void *'的间接级别与'MyClass'不同

我已经改变了我的C_Wrapper:

标头文件:

#ifdef __cplusplus
#endif

extern "C"__declspec (dllexport) void* createWrapper(double a, double b);
extern "C"__declspec (dllexport) void destoryWrapper(void* instance);
extern "C"__declspec (dllexport) double Add(void* instance, double a, double b);

#ifdef __cplusplus
#endif

源文件:

#include "stdafx.h"
#include "MyClass.h"
#include "C_DllWrapper.h"

extern "C"__declspec (dllexport) void* createWrapper(double a, double b)
{
  return new MyClass(a,b); 
}

 extern "C"__declspec (dllexport) void destoryWrapper(void *instance)
{
  delete static_cast<MyClass*>(instance);
}
 extern "C"__declspec (dllexport) double Add(void *instance, double a, double b)
{
 MyClass *myClass = static_cast<MyClass*>(instance);
 return myClass->Add(a, b);
}

是吗?

什么更好?:

extern "C"__declspec (dllexport) void* createWrapper(double a, double b)
{
  return new MyClass(a,b); 
}

 extern "C"__declspec (dllexport) void destoryWrapper(void *instance)
 {
    delete static_cast<MyClass*>(instance);
 }
  extern "C"__declspec (dllexport) double Add(void *instance, double a, double b)
  {
     MyClass *myClass = static_cast<MyClass*>(instance);
     return myClass->Add(a, b);
   }

或那:

extern "C"__declspec (dllexport) void* createWrapper(double a, double b)
{
  return new MyClass(a,b); 
}

extern "C"__declspec (dllexport) void destoryWrapper(void *instance)
{
  delete static_cast<MyClass*>(instance);
}
extern "C"__declspec (dllexport) double Add(void *instance, double a, double b)
{
 MyClass *myClass = reinterpret_cast<MyClass*>(instance);
  return myClass->Add(a, b);
}

此代码可以在调试模式下使用Visual Studio和LabVIEW运行。 没有发生错误。

现在我明白了问题: 第一个我实际上只能创建对象MyClass而我在那里做 调用createWrapper函数(double a,double b)(因此创建了对象)。 直到这里一切都好。 如果我打电话,例如,这个函数:

  extern "C"__declspec (dllexport) double Add(void *instance, double a,   double b)
  {
     MyClass *myClass = static_cast<MyClass*>(instance);
     return myClass->Add(a, b);
  }

如何告诉我的对象(指针)“MyClass”在LabVIEW中为此功能所知?

或者更确切地说我如何反对引用的指针“void * instance”。 例如,如果我编写测试程序(C ++),我将按如下方式进行:

 int main ()
{
  void * testref;
  testref = create (1.2);
  Add (testref, 5.6);
  ......
}

这是在c ++中,但在Labview中是什么。 如何为所有剩余的函数使用此对象“void * testref”。

抱歉我的英文

1 个答案:

答案 0 :(得分:2)

您的typedef正在破坏您的代码。你不需要它。当你将[{1}}重新定义为new MyClass时,typedef会导致编译器感到困惑。

  1. 删除MyClass行。
  2. void*功能的签名更改为typedef void* MyClass
  3. createWrapper添加到void* createWrapper函数定义,而不仅仅是其声明。
  4. 如果您正在开发一个C API,它是对象方法的平面表示,请考虑采用OOP式命名约定(&#34; extern "C"&#34;名称而不是使用createWrapper名称),因为在检查代码中所有函数的列表时,它们会更有条理。

    另外,不要忘记定义Noun_Verb或以其他方式释放对象实例的函数:

    VerbNoun

    我建议您阅读此质量检查以获取更多信息和大量有用示例:How to call a C++ method from C?

    我还怀疑您错误地使用了delete,因为我相信您实际上导出这些功能。我觉得直接使用extern "C" void* MyClass_create() { return new MyClass(); } extern "C" void MyClass_destroy(void* instance) { delete static_cast<MyClass*>(instance); } 而不是使用宏会更好。语法为DLLIMPORT,请参见此处:https://msdn.microsoft.com/en-us/library/a90k134d.aspx