C++ Question Structure of C++ code for orbiter

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
So, it adds some flags to your function definition (or maybe it does nothing, if DLLCLBK is an empty macro). But most probably it exactly defines the calling convention, which is a convention of how a function should be called on the machine code level.
DLLCLBK is defined as follows:
Code:
#define DLLCLBK extern "C" __declspec(dllexport)
The "__declspec(dllexport)" part tells the compiler/linker to place this function in the DLL's export table, so that Orbiter.exe can find it when it loads the DLL and runs it.

"extern "C" " tells the compiler to export the function name as if were a C function (otherwise, by default the name would be mangled, or decorated, to support C++ features such as classes, function overloading, etc). This makes it easier to find the function in the DLL using the GetProcAddress function since the core doesn't need to be aware name mangling scheme.


-----Post Added-----


What compiler do you guys use? Im using dev++ for my first MFD. I've added the libraries and headers for the SDK, and tried to compile that sample code given at the start of this thread. All I got was several errors and loads of warnings. Anyone know how to fix this?
The libraries inside OrbiterSDK are specific to Microsoft's VC++ compiler series. I personally use VC++ 2008 express edition.
This is because of the name mangling. When the MFD class is exported by dev++, its members have their names mangled according to whatever scheme dev++ uses. Since all compilers use different schemes, and Orbiter is compiled with Visual C++, Orbiter can not find the MFD class members in your DLL.

EDIT: I use Visual Studio 2005 Pro
 

escapetomsfate

OBSP Developer
Addon Developer
Joined
Jun 21, 2008
Messages
282
Reaction score
0
Points
0
Location
GB
I've just tried compiling it in VC++ 2008. I added the include directories via Project>Properties>C/C++>General and the libraries via Project>Properties>Linker>General. I compiled, and got 116 "Unresolved External Symbol" Errors. Have I not set it up right or something?
 

agentgonzo

Grounded since '09
Addon Developer
Joined
Feb 8, 2008
Messages
1,649
Reaction score
4
Points
38
Location
Hampshire, UK
Website
orbiter.quorg.org
I've just tried compiling it in VC++ 2008. I added the include directories via Project>Properties>C/C++>General and the libraries via Project>Properties>Linker>General. I compiled, and got 116 "Unresolved External Symbol" Errors. Have I not set it up right or something?
You're still missing some libraries then. Which symbols can't it resolve (it will give you the name). If it's Windows symbols (function names) then you're missing some windows libraries. If it's Orbiter-sounding function names then you're not linking to the Orbiter.lib (or whatever the orbiter libraries are - I can't remember what they are off the top of my head)
 

escapetomsfate

OBSP Developer
Addon Developer
Joined
Jun 21, 2008
Messages
282
Reaction score
0
Points
0
Location
GB
unresolved external symbol "public: virtual bool __thiscall VESSEL2::clbkLoadPanel(int)" (?clbkLoadPanel@VESSEL2@@UAE_NH@Z)

There's one. They all pretty much look like that. Thanks for the help :)

How do you link to the libraries in VC++ 2008? That must be the problem.


-----Post Added-----


Woo Just fixed it! Followed a tutorial for linking GLUT Libraries ;)
But now I have another error;

1>LINK : fatal error LNK1104: cannot open file 'msvcirt.lib'
:(
Guess I'm gonna have to get VC++ 2005. Retro :p
 
Last edited:

Bj

Addon Developer
Addon Developer
Donator
Joined
Oct 16, 2007
Messages
1,886
Reaction score
11
Points
0
Location
USA-WA
Website
www.orbiter-forum.com
1>LINK : fatal error LNK1104: cannot open file 'msvcirt.lib'
:(
Guess I'm gonna have to get VC++ 2005. Retro :p

You are supposed to ignore that library.

SDKInstall4.png
 

escapetomsfate

OBSP Developer
Addon Developer
Joined
Jun 21, 2008
Messages
282
Reaction score
0
Points
0
Location
GB
Thanks! That worked :) I added the module to Orbiter,activated, and no sim time :(
Thanks for the help though Bj
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Thanks! That worked :) I added the module to Orbiter,activated, and no sim time :(
Did you run a base-install delta-glider scenario? Some other addons also write to oapiDebugString() and they maybe overwriting what you are putting there. Consider using onscreen annotations instead (see section 19.19 of the API_Reference.pdf).

EDIT: BTW, you do know the full story on your sig, don't you?
http://www.snopes.com/business/genius/spacepen.asp
 

escapetomsfate

OBSP Developer
Addon Developer
Joined
Jun 21, 2008
Messages
282
Reaction score
0
Points
0
Location
GB
Did you run a base-install delta-glider scenario? Some other addons also write to oapiDebugString() and they maybe overwriting what you are putting there. Consider using onscreen annotations instead (see section 19.19 of the API_Reference.pdf).
Turns out I forgot to put the updated DLL file in the plug ins foler. I've just tried and it works :) Happy days :)

EDIT: BTW, you do know the full story on your sig, don't you?
http://www.snopes.com/business/genius/spacepen.asp

Yeah, I know about that. You aren't the first to remind me. Guess I better change it then ;)
 

Wraith

New member
Joined
Oct 7, 2008
Messages
59
Reaction score
0
Points
0
Location
Moscow
Code:
#define DLLCLBK extern "C" __declspec(dllexport)
By the way, there's a tiny bug in Orbiter SDK concerning this.

If you look at virtually any addon's DLL made for Orbiter, you can see stuff like
Code:
??0CELBODY@@QAE@ABV0@@Z
??0CameraMode@@QAE@ABV0@@Z
??0CameraMode_Cockpit@@QAE@ABV0@@Z
??0CameraMode_Ground@@QAE@ABV0@@Z
??0CameraMode_Track@@QAE@ABV0@@Z
??0GraphMFD@@QAE@ABV0@@Z
??0MFD@@QAE@ABV0@@Z
??0VESSEL2@@QAE@ABV0@@Z
...
in the DLLs' export tables.

That's because when building addon, these functions/methods in the SDK are declared with __declspec(dllexport), eg, CamAPI.h:
Code:
class DLLEXPORT ExternalCameraControl {
 ...

Changing DLLEXPORT to OAPIFUNC in SDK headers, then rebuilding the addon cleans up the export table.
 

escapetomsfate

OBSP Developer
Addon Developer
Joined
Jun 21, 2008
Messages
282
Reaction score
0
Points
0
Location
GB
Is there anywhere where I can see the source code for a very basic MFD? How would I just make an MFD that does nothing at all, just shows up on the menu? I've looked at CustomMFD but that looks a little complicated :S

I'm not new to C++ or custom libraries, just the orbiter ones.

EDIT: I've tried to make an MFD by cutting down CustomMFD -

Code:
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"stdafx.h"
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] PlantFlagMFD: [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] MFD {
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]:
PlantFlagMFD (DWORD w, DWORD h, VESSEL *vessel);
~PlantFlagMFD ();
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Update (HDC hDC);
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam);
};
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]struct[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] { 
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] mode; 
} g_PlantFlagMFD;
DLLCLBK [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] opcDLLInit (HINSTANCE hDLL)
{
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]char[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] *name = [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"PlantFlagMFD"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];
MFDMODESPEC spec;
spec.name = name;
spec.key = OAPI_KEY_P;
spec.msgproc = PlantFlagMFD::MsgProc;
g_PlantFlagMFD.mode = oapiRegisterMFDMode (spec);
}
DLLCLBK [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] opcDLLExit (HINSTANCE hDLL)
{
oapiUnregisterMFDMode (g_PlantFlagMFD.mode);
}
PlantFlagMFD::PlantFlagMFD (DWORD w, DWORD h, VESSEL *vessel)
: MFD (w, h, vessel)
{}
PlantFlagMFD::~PlantFlagMFD ()
{
}
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] PlantFlagMFD::MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam)
{
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]switch[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] (msg) {
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] OAPI_MSG_MFD_OPENED:
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] PlantFlagMFD (LOWORD(wparam), HIWORD(wparam), (VESSEL*)lparam));
}
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 0;
}
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] PlantFlagMFD::Update (HDC hDC)
{
Title (hDC, [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"PlantFlagMFD"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);
}
[/SIZE]

I'm eventually going to make an MFD to keep track of the Flag Challenge scenarios, but for now I just want the MFD to show up. I compiled the above code, and Vc++2008 thinks it's fine. I copy the dll into the Plugins folder, activte it, launch a scenario and it's not there. What am I doing wrong?

All help apprec. Thanks and sorry for the long post
 
Last edited:
Top