我试图通过导出为DLL(在Windows / VS 2010上)来保护某些C ++代码。
在下面的示例中,var
在超类构造函数中设置,调试器显示它肯定设置为引用某事。
测试是在代码中构造的,该代码使用了Test类包含在其中的DLL。
但是当从测试实例调用go
时(从DLL调用,但DLL消费者调用调用方法)var
是空指针(它的值为0)
这是一种简化,因为我不允许分享实际的代码。
//Headers
class Base {
public:
__declspec(dllexport) Base();
private:
Foo* var;
};
class Test : Base {
public:
__declspec(dllexport) Test();
__declspec(dllexport) void go();
private:
};
//Body
Base::Base() {
var = new Foo();
}
Test::Test() : Base() {
}
void Test::go() {
var->do_something();
}
在消费代码中,标题是
class Base {
public:
__declspec(dllimport) Base();
};
class Test {
public:
__declspec(dllimport) Test();
__declspec(dllimport) void go();
};
实际代码要复杂得多,但如果有人能告诉我dllexport是否存在对实例变量的已知限制,或者我是否更有可能在空指针上调用方法,我将不胜感激。测试,或者它可能是一个dllexport和继承问题。这个代码在我拆分使用者代码和DLL代码在同一个项目之前有效,它只是在拆分后才破坏,dllexporting / dllimporting函数我想暴露给消费者使用的第二组头文件。
答案 0 :(得分:1)
当您在“使用代码”中将值Test
从一个地方传递到另一个地方时,您将导致slicing发生,因为客户端代码不知道该变量并计算错误班级Test
的大小。
要解决此问题,您还应该在客户端代码中声明变量,或者您可以提供某种静态工厂函数,并且只允许客户端代码将指针传递给Test
。避免切片。
答案 1 :(得分:0)
如果从提供给客户的代码中删除实例变量,则只有您自己的代码知道对象的实际大小并可以创建它。从头脑中你可以通过两种方式解决这个问题:
提供createTest静态函数,用于创建类的实例(工厂方法)。这里最好的事情是提供一个纯接口(没有实例变量)。
如果您只想隐藏课程的特定部分,可以使用pimpl习语(wikipedia article)。
答案 2 :(得分:0)
有没有理由不使用:
#ifdef IN_FOO_PROJECT
# define fooEXPORT __declspec(dllexport)
#else
# define fooEXPORT __declspec(dllimport)
#endif
class fooEXPORT exportClass
{
public:
void function( void );
Foo * var;
}
如果您想要隐藏您的课程(或您班级的一部分),您可以将其用作私人会员:
#ifdef IN_FOO_PROJECT
# define fooEXPORT __declspec(dllexport)
#else
# define fooEXPORT __declspec(dllimport)
#endif
class classToHide;
class fooEXPORT exportClass
{
public:
void function( void );
classToHide * var;
}
在Cpp:
#include "exportClass.h"
#include "classToHide.h"
void exportClass::function( void )
{
var->function();
}