3Dz with Embarcadero C++ XE4

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Post Reply
Tim Frost
Posts: 5
Joined: Tue Oct 07, 2008 1:16 am
Location: Ely, Cambridge UK

3Dz with Embarcadero C++ XE4

Post by Tim Frost »

I'm using the siappdll.dll with Emabarcadero C++ XE4.

I successfully used mkexp to create an import library for a 64 bit app. However when I used implib to create an import library for a 32 bit app I found calls to si functions would often result in corrupt data, or subsequent program steps would corrupt the data. This turned out to be becauase implib was using the wrong calling convention. The work around was to dymanically load the dll using LoadLibrary and then get the address of each function using GetProcAddess. The function pointers MUST be delaired with __stdcall e.g.

header file:
typedef SpwRetVal __stdcall(*SIINITIALIZE)();
typedef void __stdcall(*SITERMINATE)();
typedef SiHdl __stdcall(*SIOPEN)(char *, SiDevID, SiTypeMask *, int, SiOpenData *);
typedef void __stdcall(*SIOPENWININIT)(SiOpenData*, HWND);
typedef SpwRetVal __stdcall(*SICLOSE)(SiHdl);
typedef SpwReturnValue __stdcall(*SIGETDEVICENAME)(SiHdl, SiDeviceName *);
typedef void __stdcall(*SIGETEVENTWININIT)(SiGetEventData*, UINT, WPARAM, LPARAM);
typedef SpwRetVal __stdcall(*SIGETEVENT)(SiHdl, int, const SiGetEventData *, SiSpwEvent *);
typedef SpwRetVal __stdcall(*SIGETDEVICEINFO)(SiHdl, SiDevInfo *);
typedef SpwRetVal __stdcall(*SIGETBUTTONNAME)(SiHdl, SPWuint32, SiButtonName *);
typedef SpwRetVal __stdcall(*SIGETDRIVERINFO)(SiVerInfo *);
typedef int __stdcall(*SIBUTTONPRESSED)(const SiSpwEvent *);
typedef int __stdcall(*SIBUTTONRELEASED)(const SiSpwEvent *);
typedef void __stdcall(*SIGETLIBRARYINFO) (SiVerInfo *);
// add more funtions as required

MyClass{
public:
HINSTANCE HLib;
SIINITIALIZE SiInitialize;
SITERMINATE SiTerminate;
SIOPEN SiOpen;
SIOPENWININIT SiOpenWinInit;
SICLOSE SiClose;
SIGETDEVICENAME SiGetDeviceName;
SIGETEVENTWININIT SiGetEventWinInit;
SIGETEVENT SiGetEvent;
SIGETDEVICEINFO SiGetDeviceInfo;
SIGETBUTTONNAME SiGetButtonName;
SIGETDRIVERINFO SiGetDriverInfo;
SIBUTTONPRESSED SiButtonPressed;
SIBUTTONRELEASED SiButtonReleased;
SIGETLIBRARYINFO SiGetLibraryInfo;

bool __fastcall LoadSiLib();
void __fastcall UnloadSiLib();
};

main file:
//---------------------------------------------------------------------------
bool __fastcall MyClass::LoadSiLib()
{
try
{
HLib = (HINSTANCE)LoadLibrary(L"siappdll.dll"); // TCHAR maps to wchar_t
}
catch (...)
{
MessageDlg("Could not load the siappdll.dll", mtError, TMsgDlgButtons() << mbOK, 0);
}

if (HLib == NULL)
{
return false;
}

SiInitialize = (SIINITIALIZE)GetProcAddress(HLib, "SiInitialize");
if (SiInitialize == NULL)
{
MessageDlg("Could not find function SiInitialize", mtError, TMsgDlgButtons() << mbOK, 0);
return false;
}

// etc...
return true;
}

//---------------------------------------------------------------------------
void __fastcall MyClass::LoadSiLib()
{
FreeLibrary(Hlib);
}
//---------------------------------------------------------------------------

Apologies the editor has messed up the indents...

In the meantime I'm not sure if this is an issue with siappdll.dll or with Embarcadero's implib utility. I have successfully implibed the siappdll.dll in the past for 32 bit apps.

Trust this helps.

Tim
Tim Frost
FrostNet Ltd
Post Reply