Exporting a class to a dll

I have this code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#ifndef _MODEL_H_
#define _MODEL_H_

#ifndef DLL_API
#define DLL_API _declspec(dllimport)
#endif

#include <d3d9.h>
#include <d3dx9.h>
#include <string>
using namespace std;

#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

class DLL_API Model
{
private:
	D3DXMATRIX Result;
	LPD3DXMESH model;
	DWORD MaterialCount;
	D3DMATERIAL9* material;
	LPDIRECT3DTEXTURE9* texture;
	static LPDIRECT3DDEVICE9 d3ddev;

public: 
	Model();

	bool GetLPDIRECT3DDEVICE9(LPDIRECT3DDEVICE9	D3DDEV);

	bool LoadModel(wstring ModelName);

	bool DrawModel();

	bool RotateModel(float RotX, float RotY, float RotZ);

	bool TranslateModel(float TransX,float TransY, float TransZ);

	bool TransRotModel(float TransX,float TransY, float TransZ, float RotX, float RotY, float RotZ);

	bool RotTransModel(float RotX, float RotY, float RotZ, float TransX,float TransY, float TransZ);

	~Model(void);
};


#endif 


The only problem is that when I try to compile I get this error
warning C4251: 'Model::Result' : struct 'D3DXMATRIX' needs to have dll-interface to be used by clients of class 'Model'

D3DXMATRIX is declared as a struct, but it's actually a class. What can I do to make it work?
What do you mean? Is it a struct or a class? I'm looking at the header right now and it says it's a struct.
You don't need to worry about that as the member is private and won't be accessed outside of your class. However you have another problem.

DLL_API should be defined to __declspec(dllexport) in the DLL that owns it and __declspec(dllimport) for modules that use it.
This is D3DXMATRIX . as you can see, it's a struct, but it has functions, so it looks like a class to me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#ifdef __cplusplus
typedef struct D3DXMATRIX : public D3DMATRIX
{
public:
    D3DXMATRIX() {};
    D3DXMATRIX( CONST FLOAT * );
    D3DXMATRIX( CONST D3DMATRIX& );
    D3DXMATRIX( CONST D3DXFLOAT16 * );
    D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14,
                FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24,
                FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34,
                FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 );


    // access grants
    FLOAT& operator () ( UINT Row, UINT Col );
    FLOAT  operator () ( UINT Row, UINT Col ) const;

    // casting operators
    operator FLOAT* ();
    operator CONST FLOAT* () const;

    // assignment operators
    D3DXMATRIX& operator *= ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator += ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator -= ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator *= ( FLOAT );
    D3DXMATRIX& operator /= ( FLOAT );

    // unary operators
    D3DXMATRIX operator + () const;
    D3DXMATRIX operator - () const;

    // binary operators
    D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const;
    D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const;
    D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const;
    D3DXMATRIX operator * ( FLOAT ) const;
    D3DXMATRIX operator / ( FLOAT ) const;

    friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& );

    BOOL operator == ( CONST D3DXMATRIX& ) const;
    BOOL operator != ( CONST D3DXMATRIX& ) const;

} D3DXMATRIX, *LPD3DXMATRIX;

#else //!__cplusplus
typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX;
#endif //!__cplusplus 
It doesn't matter. As long as you access it via methods on Model, it's not a problem. You get the same warning if you had a std::string or any other complex object.
About this __declspec(dllexport) and __declspec(dllimport). I use __declspec(dllexport) in the .cpp file. this way when I compile the file DLL_API is set to __declspec(dllexport) and when I include the .h in an other project DLL_API is set to __declspec(dllimport).

I made a class that had std::string and I didn't get that warning. This is the first time when I get that warning. I don't know what to do with that warning.
Last edited on
Ignore the warning, or switch it off with a #pragma warning
I don't want to disable the warning. I want to know why I get that warning, and why not, something to solve the problem, but not disabling the warning
To minimize the possibility of data corruption when exporting a class with __declspec(dllexport), ensure that:

* All your static data is access through functions that are exported from the DLL.
* No inlined methods of your class can modify static data.
* No inlined methods of your class use CRT functions or other library functions use static data (see Potential Errors Passing CRT Objects Across DLL Boundaries for more information).
* No methods of your class (regardless of inlining) can use types where the instantiation in the EXE and DLL have static data differences.

You can avoid exporting classes by defining a DLL that defines a class with virtual functions, and functions you can call to instantiate and delete objects of the type. You can then just call virtual functions on the type.

For more information on exporting templates, see http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958.

C4251 can be ignored in Microsoft Visual C++ 2005 if you are deriving from a type in the Standard C++ Library, compiling a debug release (/MTd) and where the compiler error message refers to _Container_base.
The warning is to let you know that you're exposing a record or type that you've not exported (using dllexport). But as the data is private, you're not exporting it in practice, but the compiler doesn't know that.

You are going to be good and only access it thru member functions of your class right? If so the correct thing to do is to ignore the warning. If you know about the warning and you don't want the compiler to keep reminding you about it, the correct thing to do is to disable the warning for that case.

If you don't want to disable the warning, that's your choice, but it's the wrong choice. What ever you do, don't try to export the data. I repeat, the correct thing to do is to access the data thru class members and ignore the warning.
Last edited on
actually I will never know what value it has. the value will be changed like this:

D3DXMatrixIdentity(&Result); this is in the constructor

this is used everyframe when I draw the object

d3ddev->SetTransform(D3DTS_WORLD,&Result);

1
2
3
4
5
6
D3DXMatrixRotationX(&RotateX,RotX);
D3DXMatrixRotationY(&RotateY,RotY);
D3DXMatrixRotationZ(&RotateZ,RotZ);
D3DXMatrixTranslation(&Translate,TransX,TransY,TransZ);

Result = Translate * RotateX * RotateY * RotateZ ;


and I run the code above only when I need to change the position of the object, store the result of the math in the Result matrix, and than use it. This way, I'll do the math only when I really need it. That variable is used in a few more places, but in the same way. Are you sure it's good to do what you said? To disable the warning...
Last edited on
Just to be clear, I'm assuming that D3DXMATRIX is defined in the same DLL as Model and is only used by members of Model.

If that's the case, yes I'm sure.
D3DXMATRIX is defined in d3dx9math.h. It's a file in DirectX SDK
Topic archived. No new replies allowed.