Personal Video Database

English => Development => Topic started by: TnS on February 21, 2009, 08:58:43 pm

Title: C++ plugin
Post 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.
Title: Re: C++ plugin
Post by: nostra on February 22, 2009, 04:16:39 am
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.
Title: Re: C++ plugin
Post by: nostra on February 22, 2009, 04:10:46 pm
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:

Code: ("PvdImportPlugin.def") [Select]
LIBRARY PvdImportPlugin.dll

EXPORTS
GetName
GetDescription
GetType
GetVersionSupported

BeginWork
EndWork

GetFilter
Parse
GetPluginLanguage

GetPluginVersion
CheckPVDVersion

CanConfig
Configure


Code: ("PvdImportPlugin.h") [Select]
#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);


Code: ("PvdImportPlugin.cpp") [Select]
// 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.
Title: Re: C++ plugin
Post by: TnS on February 22, 2009, 08:35:49 pm
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.
Title: Re: C++ plugin
Post by: nostra on February 23, 2009, 02:08:12 am
OK, I think I'll post your code in the development section.

Feel free to upload more code, if you have smth new ;)