错误 C2040:"我的类":"void *"的间接级别与"我的类"不同

error C2040: 'MyClass' : 'void *' differs in levels of indirection from 'MyClass'

本文关键字:我的 不同 C2040 void 错误      更新时间:2023-10-16

我写了一个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,我做where调用createWrapper函数(双精度a,双精度b)(因此对象被创建)。在此之前一切正常。例如,如果我调用这个函数:

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

如何告诉我的对象(指针)"我的类"使已知在LabVIEW这个功能?

或者更确切地说,我如何反对指针"void * instance"引用。例如,如果我编写一个测试程序(c++),我将按照如下步骤进行:

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

这是在c++中,但在Labview中。我怎么能得到这个对象"void * teststref "为所有剩余的函数使用。

Sorry for my english

您的typedef正在破坏您的代码。你不需要它。类型定义导致编译器在看到new MyClass时感到困惑,因为您已将MyClass重新定义为void*

  1. 删除typedef void* MyClass
  2. createWrapper函数的签名更改为void* createWrapper
  3. extern "C"添加到createWrapper函数定义,而不仅仅是其声明。

如果你正在开发一个C API,它是一个对象方法的平面表示,考虑采用oop风格的命名约定("Noun_Verb"名称而不是使用VerbNoun名称),因为当检查代码中的所有函数列表时,它们将更有组织。

另外,不要忘记定义一个delete函数,否则会释放您的对象实例:

extern "C" void* MyClass_create() {
    return new MyClass();
}
extern "C" void  MyClass_destroy(void* instance) {
    delete static_cast<MyClass*>(instance);
}

我推荐阅读这个QA以获得更多信息和大量有用的示例:如何从C调用c++方法?

我也怀疑你使用DLLIMPORT不正确,因为我相信你实际上是导出这些函数。我觉得直接使用__declspec而不是使用宏更好。语法是__declspec(dllexport),见这里:https://msdn.microsoft.com/en-us/library/a90k134d.aspx