我写了一个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”。
抱歉我的英文
答案 0 :(得分:2)
您的typedef
正在破坏您的代码。你不需要它。当你将[{1}}重新定义为new MyClass
时,typedef会导致编译器感到困惑。
MyClass
行。void*
功能的签名更改为typedef void* MyClass
createWrapper
添加到void* createWrapper
函数定义,而不仅仅是其声明。如果您正在开发一个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