Personal Video Database
English => Development => Topic started by: TnS on February 21, 2009, 08:58:43 pm
-
I made a simple import plugin in C++ but it crashes Personal Video Database right after the splash screen. :)
Tested with version 0.9.8.2 and 0.9.9.4 beta.
PVD calls the following functions before it crashes: GetVersionSupported, CheckPVDVerion, GetType, GetName, GetDescription, CanConfig, GetPluginVersion, GetPluginLanguage, GetName.
First error message:
"Exception EAccessViolation in module viddb.exe at 00006121.
Access violation at address 00406121 in module 'viddb.exe'. Read of address 00000009."
Second error message:
"Unexpected exception:
A call to an OS function failed"
I uploaded the DLL and its source to here (http://drop.io/PvdImportPlugin). Made with Visual C++ 2008 Express Edition.
-
It seems to be smth wrong with calling convention, but I do not really get it. Your library seems to work correctly if
1. I import the function without stdcall operator
or
2. You declare the "PvdCallType" with __stdcall and I import the function with stdcall in my code, but strangely the names of the exported function are changed to smth like _GetName@4, so I would need to pass these names while using GetProcAddress
I do not really like both ways as I would need to change all existing plugins to fit the new system.
Do you know why the names of exported functions get changed with __stdcall and how to prevent it?
P.S. It seems like you are preparing a kind of template for creating plugins in Visual Studio. Good idea. It would be great to have such a template.
-
OK, now I know what to do:
You should use the __stdcall call convention and export the functions using a definition file instead of __declspec(dllexport) defining proper function names in a definition file:
LIBRARY PvdImportPlugin.dll
EXPORTS
GetName
GetDescription
GetType
GetVersionSupported
BeginWork
EndWork
GetFilter
Parse
GetPluginLanguage
GetPluginVersion
CheckPVDVersion
CanConfig
Configure
#define PVDIMPORTPLUGIN_API extern "C"
#define PvdCallType __stdcall
//#define PvdCallType
typedef bool (PvdCallType *TPluginImpGenMovieCallback)(const WCHAR*);
typedef bool (PvdCallType *TPluginImpGenPersonCallback)(const WCHAR*);
PVDIMPORTPLUGIN_API WCHAR* PvdCallType GetName(int LangID);
PVDIMPORTPLUGIN_API WCHAR* PvdCallType GetDescription(int LangID);
PVDIMPORTPLUGIN_API SHORT PvdCallType GetType();
PVDIMPORTPLUGIN_API DWORD PvdCallType GetVersionSupported();
PVDIMPORTPLUGIN_API int PvdCallType BeginWork();
PVDIMPORTPLUGIN_API void PvdCallType EndWork();
PVDIMPORTPLUGIN_API WCHAR* PvdCallType GetFilter(HWND AppHandle, int LangID, WCHAR* CustomFields);
PVDIMPORTPLUGIN_API void PvdCallType Parse(HWND AppHandle, int LangID, WCHAR* FileName, TPluginImpGenMovieCallback MovieCallback, TPluginImpGenPersonCallback HumanCallback, WCHAR* CustomFields);
PVDIMPORTPLUGIN_API int PvdCallType GetPluginLanguage();
PVDIMPORTPLUGIN_API char* PvdCallType GetPluginVersion();
PVDIMPORTPLUGIN_API BOOL PvdCallType CheckPVDVersion(int V);
PVDIMPORTPLUGIN_API BOOL PvdCallType CanConfig();
PVDIMPORTPLUGIN_API BOOL PvdCallType Configure(int LangID, HWND AppHandle, WCHAR* CustomFields);
// PvdImportPlugin.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "PvdImportPlugin.h"
PVDIMPORTPLUGIN_API WCHAR* PvdCallType GetName(int LangID)
{
//MessageBox(NULL, L"", L"GetName", MB_OK);
return L"TestName";
}
PVDIMPORTPLUGIN_API WCHAR* PvdCallType GetDescription(int LangID)
{
//MessageBox(NULL, L"", L"GetDescription", MB_OK);
return L"TestDesc";
}
PVDIMPORTPLUGIN_API SHORT PvdCallType GetType()
{
//MessageBox(NULL, L"", L"GetType", MB_OK);
return 3;
}
PVDIMPORTPLUGIN_API DWORD PvdCallType GetVersionSupported()
{
//MessageBox(NULL, L"", L"GetVersionSupported", MB_OK);
return 0; // All
}
PVDIMPORTPLUGIN_API int PvdCallType BeginWork()
{
//MessageBox(NULL, L"", L"BeginWork", MB_OK);
return 0;
}
PVDIMPORTPLUGIN_API void PvdCallType EndWork()
{
//MessageBox(NULL, L"", L"EndWork", MB_OK);
}
PVDIMPORTPLUGIN_API WCHAR* PvdCallType GetFilter(HWND AppHandle, int LangID, WCHAR* CustomFields)
{
//MessageBox(NULL, L"", L"GetFilter", MB_OK);
return L"Test Files|*.test";
}
PVDIMPORTPLUGIN_API void PvdCallType Parse(HWND AppHandle, int LangID, WCHAR* FileName, TPluginImpGenMovieCallback MovieCallback, TPluginImpGenPersonCallback HumanCallback, WCHAR* CustomFields)
{
//MessageBox(NULL, L"", L"Parse", MB_OK);
}
PVDIMPORTPLUGIN_API int PvdCallType GetPluginLanguage()
{
//MessageBox(NULL, L"", L"GetPluginLanguage", MB_OK);
return 0;
}
PVDIMPORTPLUGIN_API char* PvdCallType GetPluginVersion()
{
//MessageBox(NULL, L"", L"GetPluginVersion", MB_OK);
return "0.1.1.2";
}
PVDIMPORTPLUGIN_API BOOL PvdCallType CheckPVDVersion(int V)
{
//MessageBox(NULL, L"", L"CheckPVDVerion", MB_OK);
return true;
}
PVDIMPORTPLUGIN_API BOOL PvdCallType CanConfig()
{
//MessageBox(NULL, L"", L"CanConfig", MB_OK);
return false;
}
PVDIMPORTPLUGIN_API BOOL PvdCallType Configure(int LangID, HWND AppHandle, WCHAR* CustomFields)
{
//MessageBox(NULL, L"", L"Configure", MB_OK);
return false;
}
P.S. Add the def file to the linker options of the project.
-
Thanks! It works perfectly. :)
I uploaded the working code here (http://drop.io/PvdImportPlugin). I think it is a good starting point if someone else also wants to make a C++ plugin.
-
OK, I think I'll post your code in the development section.
Feel free to upload more code, if you have smth new ;)